Can't remove event handler, adding multiple times - vb.net

I have a piece of code where I add a handler everytime the form is open, I'm working in visual basic, but the first time I enter the form everything works fine, but for the second time I have 2 handlers, if I enter a third I have 3 handlers and so on. I don't know why is this happenning.
Here is what I tried so far.
I have stored all my machines in another class but I'm sending to myForm to show them, but to add them I use this code:
Private Sub add_machine(ByRef machine As Machine)
RemoveHandler machine.imgBox.Click, AddressOf Me.imgBox_Click
AddHandler machine.imgBox.Click, AddressOf Me.imgBox_Click
Me.Controls.Add(machine.get_imgMachine)
Private Sub imgBox_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
'Some code
End Sub
Everytime I open the form I call the sub add_machine to add dinamically my machines, as you can see I send them ByRef to simplify my code I tried to put that RemoveHandler since I'm sending ByRef to avoid having more than one handler, but it's not working please help
Thanks in advance.

Two things, DONT pass machine ByRef. You are not returning a new object. Please read this link for more information on when you should use what Byval vs ByRef
Second, add your handlers during form load (or initialization) and remove them in form closing. This will help ensure you are working with references to the same object.

Related

Event handlers for object variables VB, VS

Working with a Windows.Forms.Form from the VS designer I can use the KeyDown event when it is fired on a form or on child control (I am interested in RichTextBox). But I want to use the event on a variable type RichTextBox, say:
Dim rtbx as new RichTextBox
Sub rtbx_OnKeyDown(sender as object, e as KeyEventArgs) Handles rtbx.KeyDown
VS does not understand this. There is a method OnKeyDown listed in the ObjectBrowser, which is associated with the grandparent Control class of the RichTextBox, but I have not found any way to call this method. Examples on Microsoft VB documentation show only code looking like one copied from Form.vb class.
There are two ways to attach event handlers in VB. One is to use the WithEvents keyword on a field and the Handles keyword on a method, e.g.
Private WithEvents myRichTextBox As RichTextBox
and:
Private Sub myRichTextBox_KeyDown(sender as object, e as KeyEventArgs) Handles myRichTextBox.KeyDown
That's how it works when you add controls in the designer and then have the IDE generate the event handler. If you look in the designer code file, you'll see a field declared for each control and component you added and each declared WithEvents. If you do that then the event handler remains connected to the field, even if you change the value of the field.
The other option is to use the AddHandler keyword. This is what you must do when attaching an event handler via a local variable, because they obviously cannot be declared WithEvents, e.g.
Private Sub myRichTextBox_KeyDown(sender as object, e as KeyEventArgs)
Note there's no Handles clause on the method. Then:
Dim myRichTextBox As New RichTextBox
'...
AddHandler myRichTextBox.KeyDown, AddressOf myRichTextBox_KeyDown
That event handler will remain attached to the object and, while it is not strictly necessary in some cases, it is good practice to always detach the event handler when you're done with the it:
RemoveHandler myRichTextBox.KeyDown, AddressOf myRichTextBox_KeyDown
You need a reference to the object in order to do that, so you might use a field in order to store that. If there will only be one object, you may as well declare the field WithEvents and use Handles. If there may be multiple objects then you can use a list and then loop through that list to detach the event handlers.

Visual Basic Detect Mouse Position

So i want to make a maze game in Visual Basic and if the cursor reaches a certain panel, it will show a message box ONCE and then the Form closes.
The question is How?
I've tried
Private Sub Panel1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint
If Cursor.Position = Panel1 Then
MsgBox("Completed")
Application.Exit()
End If
End Sub
And didn't work. I got
Error 1 Overload resolution failed because no accessible '=' can be
called with these arguments:
'Public Shared Operator =(left As System.Drawing.Point, right As System.Drawing.Point) As Boolean': Value of type
'System.Windows.Forms.Panel' cannot be converted to
'System.Drawing.Point'. C:\Documents and Settings\Admin\Local
Settings\Application Data\Temporary
Projects\WindowsApplication1\Form1.vb 4 12 WindowsApplication1
Remember that i want the message box to only appear once, because sometimes when the cursor is on the panel, it shows multiple msgbox until the cursor is outta there.
I want the mouse inside the panel and run a code.
I believe there is an event called 'mouse enter' event you can use so if you type the code for the messagebox in that even for the control you want them to mouseover it will pop up everytime they do that.
For it to to nly pop up once make a counter that adds 1 and dont execute that code if the counter is already on 1.
I had a little search and found: Determine whether the mouse is over a control? (over a Control pixel range)
I just knocked up a test with a button and seemed to work fine. Please adapt to your own needs.
Private Sub Button1_Paint(sender As Object, e As PaintEventArgs) Handles Button1.Paint
Debug.WriteLine(MouseIsOverControl(Button1))
End Sub
Public Function MouseIsOverControl(ByVal c As Control) As Boolean
Return c.ClientRectangle.Contains(c.PointToClient(Control.MousePosition))
End Function
In this example I've just output "true or false" to determine detection. You can test and change it to your own needs to determine what you want to do depending on 'true/false'. Hope this helps.

How do I create an event on a different form within the VB .NET application for the same device?

I'm working on a POS program where I have a POS keyboard COM control within the application. When I double click the icon, an Event is created:
Private Sub PosKeyboard_DataEvent(sender As Object, e As AxOposPOSKeyboard_CCO._IOPOSPOSKeyboardEvents_DataEventEvent) Handles PosKeyboard.DataEvent
If PosKeyboard.POSKeyData = 1 Then Exit_Button.PerformClick()
End Sub**
How do I create an event on a different form within the app for the same device?
Based on the comments so far, I will provide an answer that I think applies.
When it comes to handling events, you have a variable to which you assign an object and then you handle an event of that variable. When the assigned object raises its event, the handling method is executed. So, in your case, you need to start by declaring a variable in the form in which you want to handle the event, e.g.
Private WithEvents posKeyboard As SomeType
The WithEvents keyword is required for that variable to be able to be used in a Handles clause. I use SomeType because I don't know the actual type of your object, although I suspect that it's something like _IOPOSPOSKeyboard.
You can then write a method to handle the desired event, copying the signature from your other form:
Private Sub posKeyboard _DataEvent(sender As Object, e As AxOposPOSKeyboard_CCO._IOPOSPOSKeyboardEvents_DataEventEvent) Handles posKeyboard .DataEvent
'...
End Sub
You then need to pass in the object that will be raising the event from the other form, which you can do via a parameter in a constructor or some other method or a property setter.

When I call an pre-existing event handler from a subroutine, it doesn't come back. VB

I'm looking to call a pre-existing event handler subroutine from the form_Load event handler.
But the below doesn't work because control doesn't come back and I want to do more.
UPDATE:
I'm new to this so I don't know what the proper protocol is but...
The reason for the non-return was that a statement like the below ended the subroutines execution.
If aLabel.Tag = 1...
the fix was adding New to the declaration to create an instance of it, ie..
changing....
Dim aLabel As Label
... to ...
Dim aLabel As New Label
I'm surprised I didn't get a warning but instead they just abruptly stopped execution of the sub. That wasn't very helpful :)
Thanks again for your time guys...
(Maybe this question should be deleted now that it has served its purpose)
#konrad #karl
END OF UPDATE
What doesn't work is....
Private Sub Form1_Load...
button1_Click(sender, e) 'But Control doesn't come back.
end sub
Do I change the sender to something?
Thanks in advance
Dave
Invoking event handlers like this is a bad idea, because you are trying to simulate the event context by making sender and/or EventArgs be something else.
Instead, put the logic that you want to invoke into a Subroutine or Function and have your Form1_Load method call that; likewise if you really do have a real click event handler, then that handler code can call the method too, like this:
Private Sub Form1_Load()
DoSomeWork()
End Sub
Protected Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs)
DoSomeWork()
End Sub
Private Sub DoSomeWork()
' Put logic here that you want to do from form load and a button click
End Sub
This has the benefit of making the code cleaner, clearer and easier to maintain as you only need to change the logic in one place should you need to change the logic.
Note: Obviously, you can pass parameters to the DoSomeWork method, if need be, and change it to a Function if you need it to return something.

Converting C# to VB.net is not working

I have translated some code from C# to VB.net for the purpose of getting Folder Browser functionality. The link to the code is here.....
http://www.codeproject.com/KB/aspnet/DirectoryBrowsing.aspx
My issue is that I have not been able to correcly translate these two lines of code to VB.net.
TreeView1.TreeNodeExpanded +=new TreeNodeEventHandler(TreeView1_TreeNodeExpanded);
TreeView1.SelectedNodeChanged += new EventHandler(TreeView1_SelectedNodeChanged);
Every translator I have used has simply dropped the semicolon from the end of each line. But the editor still does not like them.
I could some help with this as it seems this effects the refresh of the selected folder in the tree view control.
I don't get to see the C drive folder unless I type the path in the text box, and the folder will still not expand.
thank you,
Use this:
AddHandler TreeView1.TreeNodeExpanded, AddressOf TreeView1_TreeNodeExpanded
AddHandler TreeView1.SelectedNodeChanged, AddressOf TreeView1_SelectedNodeChanged
Edit:
A different way to do this would be to apply it at the method level:
Protected Sub TreeView1_TreeNodeExpanded(ByVal sender as Object, ByVal e as TreeNodeEventArgs) Handles TreeView1.TreeNodeExpanded
' Some code
End Sub
Protected Sub TreeView1_SelectedNodeChanged(ByVal sender as Object, ByVal e as EventArgs) Handles TreeView1.SelectedNodeChanged
' Some code
End Sub
You should run this in debug to find out what exactly is going on. I find a lot of times when events of this nature are run in asp.net, you have a conflicting event that "resets" the controls you are attempting to change.