I am making a risk-type game for school that dynamically creates a 4x4 grid of buttons inside a table layout panel in visual basic. I have successfully created the panel and buttons with names that correspond to the row and column of the button. There are also two parallel arrays - one for button owner and the other for button number - that correspond to the owner of the button and the number of "armies" in the button. My issue is that when the user clicks a certain button, I need to reference the button name/value to know how many "armies" the button has to control the "attack" portion of the player's turn.
The following code creates the table layout panel and the buttons with names.
'Create table Dynamically
Dim ColCount As Integer = 4
Dim RowCount As Integer = 4
Dim f As New System.Drawing.Font("Arial", 15)
riskTable.AutoScroll = True
riskTable.Dock = DockStyle.Fill
riskTable.ColumnCount = ColCount
riskTable.RowCount = RowCount
For rowNo As Integer = 0 To riskTable.RowCount - 1
For columnNo As Integer = 0 To riskTable.ColumnCount - 1
Dim buttonname As String
buttonname = "B" & rowNo & columnNo
Dim button As Control = New Button
button.Size = New Size(179, 100)
button.Name = buttonname
button.Text = "1"
button.ForeColor = Color.White
button.Font = f
AddHandler button.Click, AddressOf buttonname_Click
riskTable.Controls.Add(button, columnNo, rowNo)
Next
Next
Me.Controls.Add(riskTable)
This is the dynamic event handler that I created. I tried using 'Me.Click' to get the name of the button, but it only returns the name of the form. I need to have code in here that references the name of the currently clicked button to then in turn reference the box owner and box number arrays.
Private Sub buttonname_Click(sender As Object, e As EventArgs) Handles Me.Click
MessageBox.Show(Me.Name)
End Sub
Any help would be greatly appreciated! I think that once I get this working, the rest of the game will be pretty simple to figure out.
Thanks!
Put the name in 'button.Tag' instead/also:
button.Tag = buttonname
Then it is easy to get the name with:
Private Sub buttonname_Click(sender As Object, e As EventArgs) Handles Me.Click
Dim result As String = CType(CType(sender, System.Windows.Forms.Button).Tag, String)
End Sub
(Check the System.Windows.Forms.Button though, might need some tweak to match your buttons inside the table. riskTable.Controls.button ?)
Related
My DataGridView have some columns I want to turn a different color to indicate that they are auto-fill columns and does not need user input.
So I created the code to color columns:
Private Sub autocolumn()
Dim auto_cell As New DataGridViewCellStyle
auto_cell.BackColor = Color.LightSteelBlue
ProjTable.Columns(3).DefaultCellStyle = auto_cell
ProjTable.Columns(5).DefaultCellStyle = auto_cell
ProjTable.Columns(9).DefaultCellStyle = auto_cell
ProjTable.Columns(10).DefaultCellStyle = auto_cell
End Sub
And then place it into form Load event
Private Sub projectentry_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
autocolumn()
End Sub
On testing the form, the first row is colored no problem. Issue is on the 2nd row the color is white. Then the 3rd row its colored, and thee following white. And it follows this repeated pattern.
I even tried to make a DataGridView Rows Added event to call the sub
Private Sub color_load() Handles ProjTable.RowsAdded
autocolumn()
End Sub
Again same result. What may be the problem here?
I need to create many dropdownlists at runtime and select a different item for each one.
To avoid accessing the DB continuously I create a single dropdownlist of which I copy the items in the cloned dropdownlists. Strangely all the dropdownlists created select the item of the last dropdownlist and I don't understand why! I had to insert the cleaning of the selected items ["DlistClone.ClearSelection ()"] because otherwise the code goes wrong. Can anyone help me? thanks
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim MyRow As New TableRow
Dim MyCell As New TableCell
Dim DList As DropDownList
Dim DlistClone As DropDownList
DList = New DropDownList
DList.Items.Add("1")
DList.Items.Add("2")
DList.Items.Add("3")
MyRow = New TableRow
MyCell = New TableCell
DlistClone = New DropDownList
ClonaDList(DList, DlistClone)
DlistClone.ClearSelection()
DlistClone.Items.FindByText("3").Selected = True
MyCell.Controls.Add(DlistClone)
MyRow.Cells.Add(MyCell)
Table1.Rows.Add(MyRow)
MyRow = New TableRow
MyCell = New TableCell
DlistClone = New DropDownList
ClonaDList(DList, DlistClone)
DlistClone.ClearSelection()
DlistClone.Items.FindByText("2").Selected = True
MyCell.Controls.Add(DlistClone)
MyRow.Cells.Add(MyCell)
Table1.Rows.Add(MyRow)
End Sub
Sub ClonaDList(ByVal Origine As DropDownList, ByVal Destinazione As DropDownList)
Dim I As Integer
Dim EleList As ListItem
For I = 0 To Origine.Items.Count - 1
EleList = Origine.Items(I)
Destinazione.Items.Add(EleList)
Next I
End Sub
Ok, I got it myself!
When I do
EleList = Origin.Items (I)
Destination.Items.Add (EleList)
I create an inadvertent binding between the source Dropdownlist and the destination one.
To interrupt the binding I must necessarily use a bridge between the two controls, in this case I use the Listitem object by setting the 2 properties in 2 successive steps
Sub ClonaDList(ByRef Origine As DropDownList, ByRef Destinazione As DropDownList)
Dim I As Integer
Dim EleList As ListItem
For I = 0 To Origine.Items.Count - 1
EleList = New ListItem
EleList.Text = Origine.Items(I).Text
EleList.Value = Origine.Items(I).Value
Destinazione.Items.Add(EleList)
Next I
End Sub
Did I say it right?
I have a VBA UserForm in Excel, with very simple code. It displays a collection (a dictionary, actually) of objects, one at a time, with buttons for "first, previous, next, and last". Everything works great, but if I were to continually click the next button to go through the items, I have to click it slowly (roughly once a second). If I click any faster, the click is ignored. For example, if I click four times over two seconds, it will only 'register' the first and third click and advance twice, instead of four times.
Below is example code for the 'next' button (and the other applicable pieces of code in the userform module):
Private dQIDs As Dictionary
Public Sub TransferQIDs(ByVal dIncomingQIDs As Dictionary)
Set dQIDs = dIncomingQIDs
End Sub
Private Sub bNext_Click()
Call LoadQID(CLng(lIndex.Caption) + 1)
End Sub
Private Sub LoadQID(lQID As Long)
Dim QID As cQID
Set QID = dQIDs(lQID)
lIndex.Caption = lQID
lItems.Caption = "Viewing new QID " & lQID & " of " & dQIDs.Count
Me.tQID = QID.lQID
Me.tTitle = QID.sTitle
Me.tVID = QID.sVendorID
Me.bOS = QID.bOSPatch
Me.bApp = Not QID.bOSPatch
Me.bPrev.Enabled = Not (lQID = 1)
Me.bFirst.Enabled = Not (lQID = 1)
Me.bNext.Enabled = Not (lQID = dQIDs.Count)
Me.bLast.Enabled = Not (lQID = dQIDs.Count)
End Sub
Any ideas?
Personally I would just disable to button while content is loaded.
Private Sub bNext_Click()
Dim b1 As Button
Set b1 = ActiveSheet.Buttons("LoadQID")
REM or Me.LoadQID
b1.Font.ColorIndex = 15
b1.Enabled = False
Application.Cursor = xlWait
Call LoadQID(CLng(lIndex.Caption) + 1)
b1.Enabled = True
b1.Font.ColorIndex = 1
Application.Cursor = xlDefault
End Sub
Reason why this happens is that accessing a single object takes quite a bit of time in Excel. This way if you can click it will be registered.
Alternatively you can toggle UI update with:
Application.ScreenUpdating = False
Application.ScreenUpdating = True
windows is checking for a doubleclick. so if you click fast it registers a doubleclick.
2 options. increase you doubleclick speed in the windows mouse settings
or make a doubleclick event
I'm looking to have my excel sheet with a split in it (vertically) ensuring a set of controls stay on the left of the screen for easy access. Currently Im using this code to select and move to a cell, based on a list of headings I have in the A column.
Option Explicit
Dim trimProcess() As String
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim i As Integer
If Not Intersect(ActiveCell, Range("A6:A1000")) Is Nothing Then
If ActiveCell.Value <> "" Then
For i = 0 To UBound(trimProcess)
If ActiveCell.Value = trimProcess(i) Then
Cells(4, 4 * (i + 1)).Select
Cells(4, 4 * (i + 1)).Activate
End If
Next
End If
End If
End Sub
This works fine for what I need, but it only works in the active split view IE if I click a cell in A in the left split, it moves the left split view. I want it so that the changes only the right view, but cant find the code to do so. Is this possible?
Using VB6
Listview
ID Name
001 Raja
002 Ramu
003 Sajee
..
…
Code
Private Sub listview1_DblClick()
If Not (listview1.SelectedItem Is Nothing) Then
Textbox1.text = listview1.selectedItem(0)
Textbox2.text = listview1.SelectedItem(1)
End If
End Sub
Above code is not showing the values in the text box
How to show the list view row values in the text box.
Need VB6 Code Help
The ListView SelectedItem property does not return a collection of items selected on your ListView, so therefore you can't explicitly get the first selected item, the second selected item, etc. You will need to loop through all ListItems in your ListView and check if each is selected. If it is, do what you want to do.
One problem I see with your sample code is you're using the ListView DblClick event. I might be wrong, but it looks like whenever it fires only one ListView item can be selected (the one that fired the event). A solution for this is to put your code into a new procedure. Here's one that should work:
Private Sub GetSelectedItems()
' Make sure exactly two items are selected on our ListView.
If (CheckListViewSelectedItemCount(listview1, 2)) Then
Dim blnFoundFirstItem As Boolean
blnFoundFirstItem = False
Dim i As Integer
' Find out which items are selected.
For i = 1 To listview1.ListItems.Count
If (listview1.ListItems(i).Selected) Then
' Assign the Text of the 'first' selected item to Textbox1.Text.
If (Not blnFoundFirstItem) Then
Textbox1.Text = listview1.ListItems(i).Text
blnFoundFirstItem = True
' Assign the Text of the 'second' selected item to Textbox2.Text.
Else
Textbox2.Text = listview1.ListItems(i).Text
End If
End If
Next i
Else
MsgBox "You need to select two items."
End If
End Sub
I'm not sure in which order ListItems are iterated through in my For loop. It's possible that what would be assigned to Textbox1.Text in my code you might want to assign to Textbox2.Text.
Your code required at that at least two items are selected on the ListView. I don't know if VB6 has a way to return the number of selected items so I wrote a small function that does this:
' Return True if the passed ListView control has a number of selected items that's equal to the intExpectedItemCount parameter.
Private Function CheckListViewSelectedItemCount(listView As listView, intExpectedItemCount As Integer) As Boolean
Dim intSelectedItemCount As Integer
intSelectedItemCount = 0
Dim i As Integer
For i = 1 To listView.ListItems.Count
If (listView.ListItems(i).Selected) Then
intSelectedItemCount = intSelectedItemCount + 1
End If
Next i
CheckListViewSelectedItemCount = (intSelectedItemCount = intExpectedItemCount)
End Function
I dont have vb6 at hand and its been a while since I used it, but if memory serves me right:
ListView1.SelectedItem will return you a ListViewItem which gives you a Text property along with SubItems property that gives you access to associated columns as an array.