Index Selection in ListView created at runtime in Visual Basic (Visual Studio 2019) - vb.net

I am trying to use a ListView box created at runtime and I am able to populate items but the SelectedIndexChanged event is not working. I know I am missing something really simple. Below is a minimal working example where I am creating the ListView on a button click and populating with a couple of items. When I select an item nothing happens in the SelectedIndexChanged event.
Public Class Form1
Dim lstMylist As ListView
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
lstMylist = New ListView()
lstMylist.Location = New Point(37, 312)
lstMylist.Size = New Size(150, 150)
Me.Controls.Add(lstMylist)
lstMylist.View = View.SmallIcon
Dim myListItem1 As ListViewItem
myListItem1 = lstMylist.Items.Add("Item 1")
Dim myListItem2 As ListViewItem
myListItem2 = lstMylist.Items.Add("Item 2")
End Sub
Private Sub lstMylist_SelectedIndexChanged(sender As Object, e As EventArgs)
MessageBox.Show("I am here")
Select Case lstMylist.FocusedItem.Index
Case 0
MessageBox.Show("item 1")
Case 1
MessageBox.Show("item 2")
Case Else
MessageBox.Show("invalid")
End Select
End Sub
End Class

You need to add the event handler to the ListView SelectedIndexChanged event
lstMylist = New ListView()
lstMylist.Location = New Point(37, 312)
lstMylist.Size = New Size(150, 150)
' Add the event handler for the listview
AddHandler lstMyList.SelectedIndexChanged, AddressOf lstMylist_SelectedIndexChanged
Me.Controls.Add(lstMylist)
lstMylist.View = View.SmallIcon
As outlined by djv it is important to call RemoveHandler if you remove the ListView
RemoveHandler lstMyList.SelectedIndexChanged, AddressOf lstMylist_SelectedIndexChanged

Steve's answer will work. But an alternative is to simply make your ListView WithEvents
Dim WithEvents lstMylist As ListView
and add Handles to the method declaration
Private Sub lstMylist_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lstMylist.SelectedIndexChanged
This is more a VB.NET way of doing things. AddHandler is similar to C# Event += new EventHandler syntax.
Note, if using AddHandler, a matching RemoveHandler should appear if the ListView is to be removed and added repeatedly.

Related

Add click events to ToolStripTextBox in VB.NET when created in code

I am creating tabs to keep track of open files. When I create them I can set their properties and add them to the list in a MenuStrip.
Before I do so I want to add a click event function. Since this is in a function and will be run multiple times, I need to have a dynamic way to do add these event handlers. I cannot write this:
Private Sub ToolStripTextBox1_Click(sender As Object, e As EventArgs) Handles ToolStripTextBox1.Click
' ...
End Sub
If I do this I can only name them all one name. I want to be able to add a click event that applies to them separately as individual items.
UPDATE:
Dim textFile As ToolStripTextBox = New ToolStripTextBox("textFile")
FileList.Items.Add(textFile)
textFile.Text = filename
textFile.ReadOnly = True
textFile.BackColor = Color.FromArgb(61, 61, 61)
textFile.ForeColor = Color.White
This is the creation and personalization code. Though when you guys suggested AddButton_Click() Handles AddButton.Click It doesn't work because AddButton isn't an actual button
You can keep track of the items, add add and remove click handlers with the following code
Private FileList As New List(Of ToolStripItem)()
' put this code where you add an item
Dim filename = "whatever"
Dim textFile As ToolStripTextBox = New ToolStripTextBox(filename)
textFile.Text = filename
textFile.ReadOnly = True
textFile.BackColor = Color.FromArgb(61, 61, 61)
textFile.ForeColor = Color.White
add(textFile)
Private Sub clickHandler(sender As Object, e As EventArgs)
Dim item = DirectCast(sender, ToolStripItem)
MessageBox.Show(item.Text)
End Sub
Private Sub add(textFile As ToolStripItem)
FileList.Add(textFile) ' Since I don't know what FileList is, I ued List
AddHandler textFile.Click, AddressOf clickHandler
OpenProjectToolStripMenuItem.DropDownItems.Add(textFile) ' add to whatever menu item you normally do
End Sub
Private Sub remove(textFile As ToolStripItem)
FileList.Remove(textFile)
RemoveHandler textFile.Click, AddressOf clickHandler
OpenProjectToolStripMenuItem.DropDownItems.Remove(textFile)
End Sub
The sample click event in your code includes this:
sender As Object
You can re-use this one event handler, because whichever menu item is clicked will be the sender. So you do something like this:
Private Sub ToolStripTextBox1_Click(sender As Object, e As EventArgs) Handles ToolStripTextBox1.Click
Dim menuItem = DirectCast(sender, ToolStripMenuItem)
If menuItem Is Nothing Then Return
'If you need to choose different code for each item:
Select Case menuItem.name
Case "some item"
Case "some other item"
End Select
End Sub
And you can connect your dynamic toolstrip items to this method using AddHandler:
AddHandler myMenuStrip.Click, AddressOf ToolSTripTextBox1_Click

VB: adding object to a tabcontrol tab which doiesnt exist at this time

i want to add a tabcontrol tab by pressing on a button:
Dim inp As String
inp = TextBox6.Text
TabControl2.TabPages.Add(inp)
and when i open this tabpage some object should be already created like a button and a textbox, etc.
i havent found any type of onload events for a tabpage so i tried to add this with:
TabPage8.Controls.Add(New Button())
tabpage8 would be the name of the new created tabpage but like vb already told me, i cant add objects to a tabpage which doesnt exist at that time.
is there any way i can do that or have you any other ideas which could help me?
Your code is close. Try the following:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
TabControl2.TabPages.Add("Test")
Dim tp = TabControl2.TabPages(TabControl2.TabPages.Count - 1)
Dim b = New Button()
b.Text = "My Button"
tp.Controls.Add(b)
AddHandler b.Click, AddressOf MyButton_Click
End Sub
Private Sub MyButton_Click(sender As Object, e As EventArgs)
MessageBox.Show("MyButton clicked")
End Sub
This code grabs the last page added and adds a button to it. It also configures the button as needed and adds an event handler.

SelectionChanged event occurs more times than it should

I have grid and those grid is populate on Form's load event. At the end line of that event i am hooking method handler for my SelectionChanged event of this grid. I want to get current selected row's zero cell's 1 value. Unfortunately when i run program my SelectionChanged event method handler is called infinite times... And i have no idea why is that.
So its basically like this:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
some code which populating data to grid...
'here hooking up method after data is there already to not fire it up during grid population
AddHandler gridArtikels.SelectionChanged, AddressOf gridArtikels_SelectionChanged
End Sub
and this is event handler method itself:
Private Sub gridArtikels_SelectionChanged(sender As Object, e As GridEventArgs)
RemoveHandler gridArtikels.SelectionChanged, AddressOf gridArtikels_SelectionChanged
If gridArtikels.PrimaryGrid.Rows.Count > 0 Then
gridArtikels.PrimaryGrid.SetSelectedRows(0, 1, True)
ItemPanelImgs.Items.Clear()
'Dim images As New List(Of Article_Image)
Dim selectedNummer As String = String.Empty
selectedNummer = gridArtikels.PrimaryGrid.SelectedRows(0).Cells(1).Value.ToString()
'images = ArtikelsAndTheirVariationsFinal.GetImagesForArticle(selectedNummer)
'ItemPanelImgs.DataSource = images
End If
AddHandler gridArtikels.SelectionChanged, AddressOf gridArtikels_SelectionChanged
End Sub
P.S I am using to be concrete supergrid control from DotnetBar devcomponenets but it shouldn't be diffrent from ordinary controls behaviour.
What could be wrong here?
For those whom would like to debug here is sample app
EDIT:
I also tried this way but its still going to infinitive loop...
Public IgnoreSelectionChanged As Boolean = False
Private Sub gridArtikels_SelectionChanged(sender As Object, e As GridEventArgs) Handles gridArtikels.SelectionChanged
If IgnoreSelectionChanged Then Exit Sub
IgnoreSelectionChanged = True
If gridArtikels.PrimaryGrid.Rows.Count > 0 Then
gridArtikels.PrimaryGrid.SetSelectedRows(0, 1, True)
ItemPanelImgs.Items.Clear()
'Dim images As New List(Of Article_Image)
Dim selectedNummer As String = String.Empty
selectedNummer = gridArtikels.PrimaryGrid.SelectedRows(0).Cells(1).Value.ToString()
'images = ArtikelsAndTheirVariationsFinal.GetImagesForArticle(selectedNummer)
'ItemPanelImgs.DataSource = images
End If
IgnoreSelectionChanged = False
End Sub

Raising events from a List(Of T) in VB.NET

I've ported a large VB6 to VB.NET project and while it will compile correctly, I've had to comment out most of the event handlers as to get around there being no array collection for winform objects and so putting the various objects that were in at the collection array into a List object.
For example, in VB6 you could have an array of Buttons. In my code I've got
Dim WithEvents cmdButtons As New List(Of Button)
(and in the Load event, the List is propagated)
Obviously, you can't fire an event on a container. Is there though a way to fire the events from the contents of the container (which will have different names)?
In the Button creation code, the event name is there, but from what I understand the handler won't intercept as the Handles part of the code is not there (commented out).
I'm not exactly sure what you're after, but if you want to be able to add event handlers to some buttons in a container and also have those buttons referenced in a List, you can do something like
Public Class Form1
Dim myButtons As List(Of Button)
Private Sub AddButtonsToList(targetContainer As Control)
myButtons = New List(Of Button)
For Each c In targetContainer.Controls
If TypeOf c Is Button Then
Dim bn = DirectCast(c, Button)
AddHandler bn.Click, AddressOf SomeButton_Click
myButtons.Add(bn)
End If
Next
End Sub
Private Sub SomeButton_Click(sender As Object, e As EventArgs)
Dim bn = DirectCast(sender, Button)
MsgBox("You clicked " & bn.Name)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' GroupBox1 has some Buttons in it
AddButtonsToList(GroupBox1)
End Sub
End Class

How to code a Button's Click Event?

I'm using winform and fb.net.
Can someone provide me with an example of how to create a buttons click event?
I have
dim but as windows.forms.button
but.name
but.text
but.location
etc.
but I how do I create the Click and the code behind it?
You can use:
AddHandler button.Click, AddressOf HandlerMethod
In VB you can specify that a method handles a particular event for a particular control, if you're not creating it on the fly - you only need AddHandler when you're (say) dynamically populating a form with a set of buttons.
Here's a short but complete example:
Imports System.Windows.Forms
Public Class Test
<STAThread>
Public Shared Sub Main()
Dim f As New Form()
Dim b As New Button()
b.Text = "Click me!"
AddHandler b.Click, AddressOf ClickHandler
f.Controls.Add(b)
Application.Run(f)
End Sub
Private Shared Sub ClickHandler(sender As Object, e As EventArgs)
Dim b As Button = DirectCast(sender, Button)
b.Text = "Clicked"
End Sub
End Class
EDIT: To close the form, the simplest way is to get the form of the originating control:
Private Shared Sub ClickHandler(sender As Object, e As EventArgs)
Dim c As Control = DirectCast(sender, Control)
Dim f as Form = c.FindForm()
f.Close()
End Sub
In the winforms designer, add a button then double-click it. This will create the event (based on the button's name) and take you to the event's code.