SelectionChanged event occurs more times than it should - vb.net

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

Related

InvokeMember("click") does not trigger WebBrowser.DocumentCompleted event

This old unresolved question seems to relate most to my issue WebBrowser control not responding to InvokeMember("click")
The main difference is where the conversation petered out, my webpage does respond to ContentPlaceHolder1_btnComtrsView.click() correctly, where in the original question it did not.
I am trying to pull up a lat/long result after clicking the "View" button after entering in a value for COMTRS (use "M11S19E20" for example): https://www.earthpoint.us/TownshipsCaliforniaSearchByDescription.aspx
I've got the 2 separate document completed event handlers working correctly and all of that. So is it possible to handle the event of the document updating after clicking view? My code does work if I just click once to load the page and click, and a second time to pull the data out.
WebBrowserTRS.ScriptErrorsSuppressed = True
AddHandler WebBrowserTRS.DocumentCompleted, AddressOf ClickViewButton
WebBrowserTRS.Navigate("https://www.earthpoint.us/TownshipsCaliforniaSearchByDescription.aspx")
Private Sub ClickViewButton(sender As Object, e As WebBrowserDocumentCompletedEventArgs)
If e.Url.ToString() = "about:blank" Then Return
RemoveHandler WebBrowserTRS.DocumentCompleted, AddressOf ClickViewButton
Dim trsDoc As HtmlDocument = WebBrowserTRS.Document
Dim elem_Input_Submit As HtmlElement = trsDoc.GetElementById("ContentPlaceHolder1_btnComtrsView")
trsDoc.GetElementById("ContentPlaceHolder1_Comtrs").InnerText = _comtrs
AddHandler WebBrowserTRS.DocumentCompleted, AddressOf GetLatLong
elem_Input_Submit.InvokeMember("click")
End Sub
Private Sub GetLatLong(sender As Object, e As WebBrowserDocumentCompletedEventArgs)
RemoveHandler WebBrowserTRS.DocumentCompleted, AddressOf GetLatLong
Dim trsDoc As HtmlDocument = WebBrowserTRS.Document
Dim centroidFound As Boolean = False
For Each el As HtmlElement In trsDoc.GetElementsByTagName("tr")
Dim val As String
For Each el1 As HtmlElement In el.GetElementsByTagName("TD")
val = el1.InnerText
If val IsNot Nothing AndAlso val.Contains("Centroid") Then
centroidFound = True
' ...
WebBrowserTRS = New WebBrowser
Return
End If
Next
Next
If Not centroidFound Then
MsgBox("Unable to parse the township and range.",
MsgBoxStyle.Information, "Error in location lookup")
End If
Cursor = Cursors.Default
toolstripViewMap.Enabled = True
End Sub

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

Index Selection in ListView created at runtime in Visual Basic (Visual Studio 2019)

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.

Button Array - how to pass a parameter to shared handler

I have a bit of code where i have a dynamically created array or buttons with staff pictures on them, as well as the staff's name. I've added one handler to handle any button click from any of the buttons. where i am stuck is, if you look at the code below, it all works fine, and if you click any of the buttons you get the "aha" test message. but i want the name of the staff clicked on (so btnArray(i).Text) to be passed to the handler for further processing. I tried adding a ByVal parameter to the handler but that caused an error. what's the correct way to do this? As i said, the code below works for me, i just am at a loss as to how to add the extra functionality.
Dim btnArray(staffcount) As System.Windows.Forms.Button
For i As Integer = 1 To staffcount - 1
btnArray(i) = New System.Windows.Forms.Button
btnArray(i).Visible = True
btnArray(i).Width = 80
btnArray(i).Height = 101
btnArray(i).BackgroundImage = Image.FromFile(picloc(i))
btnArray(i).BackgroundImageLayout = ImageLayout.Stretch
btnArray(i).Text = staffname(i)
Dim who As String
who = btnArray(i).Text
AddHandler btnArray(i).Click, AddressOf Me.theButton_Click
btnArray(i).ForeColor = Color.White
btnArray(i).TextAlign = ContentAlignment.BottomCenter
Dim fnt As Font
fnt = btnArray(i).Font
btnArray(i).Font = New Font(fnt.Name, 10, FontStyle.Bold)
FlowLayoutPanel1.Controls.Add(btnArray(i))
Next i
End Sub
Private Sub theButton_Click()
MsgBox("aha")
End Sub
First, correct the signature of your shared handler.
Private Sub theButton_Click(sender As Object, e As EventArgs)
End Sub
Once that is done getting the text of the button clicked is a simple matter.
Private Sub theButton_Click(sender As Object, e As EventArgs)
Dim textOfButtonClicked As String = DirectCast(sender, Button).Text
MessageBox.Show(textOfButtonClicked)
End Sub
The sender is the button that was clicked. Since signatures use objects for the sender the DirectCast 'changes' it to button and you then can access the .Text property of the button.
If there are more manipulations you want to perform on the clicked button you could do it this way
Private Sub theButton_Click(sender As Object, e As EventArgs)
Dim whBtn As Button = DirectCast(sender, Button) ' get reference to button clicked
Dim textOfButtonClicked As String = whBtn.Text
MessageBox.Show(textOfButtonClicked)
'e.g. change the color
whBtn.BackColor = Color.LightYellow
End Sub

How do I add then select the dynamic control I just added

I've got an application in VB.net which adds a picturebox to the selected mouse position within another picturebox control. I need to create a click event to select that new picturebox so I can drag it and drop it to a new location in the event that the first one was wrong or use a keypress event, those events I will code later, but I can not figure out how to select ANY of the dynamic controls.
In vb6 there was a way to select an index of the control, but there is no such animal in VB.net.
I've tried control groups, but for some reason I'm not getting results from them.
Here is the code I have so far
Private Sub PictureBox1_Click(sender As System.Object,
e As System.EventArgs) Handles PictureBox1.Click
Dim pb As New PictureBox
pb.BackColor = Color.Blue
Me.PictureBox1.Controls.Add(pb)
pb.Size = New Size(64, 110)
pb.Location = New Point(Cursor.Position.X - 64, Cursor.Position.Y - 110)
pb.Visible = True
End Sub
What in the name of all good things am I doing wrong here?
You need to write a generic event handler before time, using the sender parameter to refer to the object that raised the event.
Private Sub PictureBoxes_Click(sender As Object, e As EventArgs)
Dim pb = DirectCast(sender, PictureBox)
'Use pb here.
End Sub
When you create your control at run time, use an AddHandler statement to attach the method to the event.
Dim pb As New PictureBox
AddHandler pb.Click, AddressOf PictureBoxes_Click
That said, if you want to implement drag-n-drop then it's not the Click event you should be handling.
This little bit of code took some time, but I was able to do what I set out to so far...
This is before the Sub Main event
Public Class dynamicPB 'create a picturebox element which
'can be called anytime
Inherits PictureBox 'sets the type of control to a
'picturebox
Public Sub New() 'sets the function of the new box to
'default values
MyBase.BackColor = Color.AliceBlue
MyBase.BorderStyle = Windows.Forms.BorderStyle.Fixed3D
MyBase.Height = 50
MyBase.Width = 26
End Sub
End Class
in the actual main class
Private Sub <control_event> (blah...) Blah...
Dim intPosAdj_X As Integer = 13 'get an offset for the cursor
Dim intPosAdj_Y As Integer = 25
Dim newPictureBox As New dynamicPB 'sets the click of the mouse into a
'mode of drawing a new PB
With newPictureBox 'clean use of the code
AddHandler newPictureBox.Click, _
AddressOf PictureBox_Click 'establishes events for the mouse
'activity on the objects
AddHandler newPictureBox.MouseEnter, _
AddressOf PictureBox_MouseEnter
AddHandler newPictureBox.MouseLeave, _
AddressOf PictureBox_MouseLeave
pbName += 1 'gives a unique name to the
'picturebox in an "array" style
.Location = New System.Drawing.Point _
(xPos - intPosAdj_X, yPos - intPosAdj_Y) 'establish where the box goes
'and center the object on the
'mouse pointer
.Visible = True 'ensures that the box is visible
.Name = pbName 'names the new control
End With
Controls.Add(newPictureBox) 'add control to form
End Sub
Private Sub PictureBox_Click(sender As System.Object, e As System.EventArgs)
Dim dblMouseClick As Double = CType(DirectCast _
(e, System.Windows.Forms.MouseEventArgs).Button, MouseButtons) _
'make it simple to manipulate
'the event by putting the long
'code into a variable
If dblMouseClick = MouseButtons.Left Then
MsgBox("Left CLick")
ElseIf dblMouseClick = MouseButtons.Right Then
MsgBox("right click")
Else
MsgBox("Center")
End If
This actually resolves the issue of adding and being able to select the object
Thanks for all of the suggestions and help