Okay so I've created a list of objects from a class like
For B As Integer = 0 To 5
clients.Add(New Client)
AddHandler clients(B).OnMessage, AddressOf clients_OnRec
Next
Then this is the event declaration
Public Event OnRec As EventHandler
This is my Event
Private Sub clients_OnRec(ByVal sender As Object)
'Does something
End Sub
My question is how can i determine which instance of the class in the list raised the event. I need to be able to do something like:
clients(whateveronefiredit).ExecuteMethodInClass
How can i do that?
:) Let me try explaining what is happening
Now in the list you have 5 objects of type Client and all this 5 of them call the event handler clients_OnRec on some kind of event.
When the first client raises this event the sender in the event handler signature Private Sub clients_OnRec(ByVal sender As Object) will have the client objects reference which raised the event.
so, in order to call the method ExecuteMethodInClass on the object which raised the event, you would do the following:
Private Sub clients_OnRec(ByVal sender As Object)
Dim c As Client = CType(sender, Client) 'Cast the sender object as Client object
c.ExecuteMethodInClass() 'This executes the ExecuteMethodInClass on the Client object which raised this event
End Sub
Hope that is clear.
Cheers
Related
Why event handler dose not respond to the event when the object created
when I tried to raise a private event at the same way the private event raised and handled as expected
Public Class Form1
Dim WithEvents nClass As Class1
Private Sub nClass_Created(ByVal sender As Object, ByVal e As System.EventArgs) Handles nClass.Created
MessageBox.Show("Created !")
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
nClass = New Class1
End Sub
End Class
Public Class Class1
Event Created(ByVal sender As Object, ByVal e As EventArgs)
Sub New()
'some codes
'when finish
RaiseEvent Created(Me, New EventArgs)
End Sub
End Class
This concept is broken, logically. In order to raise an event, there has to be an event handler attached to the event. In order to attach a handler, the object has to exist. In order to exist the constructor must complete. You'll never be able to have a constructor raise an event because the delegate list will be empty when the constructor is running (no handlers will have been added)
This would be easier to see in C#, this is how we attach events to things:
var thing = new Thing();
thing.Event += new EventHandler(NameOfSomeMethod);
VB has a similar construct:
Dim thing as New Thing()
AddHandler(thing.Event, AddressOf(NameOfSomeMethod))
As you can see, the thing has to be constructed first. The constructor code could certainly invoke the event, but there won't be any handlers attached so nothing will happen
If you want to get notified every time an object is created use a Factory pattern; the class that constructs your class can raise the event that the class has been created
I create an object of an inherited class. One of its events is to fire on change in a list. I tried writing up an example, but I found it far easier to put down my logic. By "an event is raised", I mean RaiseEvent. This is also my first time with custom events, and inheritable classes.
Create Object of Inherited Class (in its own thread)
Inherited Class runs MyBase.New()
Base Class starts listening for incoming requests
If request is received and valid, an event from Base Class is raised which is handled by the Inherited Class (with this event a list might be modified)
If list is changed, an event from Inherited Class is raised and is handled by the GUI
Base Class returns to waiting for a new request
I'm trying to avoid editing the GUI from the inherited class. The problem is the event never fires (it ignores the RaiseEvent in Step 5, and the GUI never gets an event). Possibly the separate thread is an issue?
Example of Step 5:
Private Sub RequestReceived(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.RequestReceived
'RequestReceived is from the Base Class
Dim requestType As String = sender
If requestType = "Type1" Then
RequestIsVariantOne(sender)
Else Then
'Handle other variants similarly
End If
End Sub
Private Sub RequestIsVariantOne(ByVal sender As Object)
'Conditional statements go here that determine whether or not to edit the list
'The statements will exit the Sub if it the list should not be edited.
'If Sub hasn't exited yet, now we edit the list.
ThatList.Add(sender)
'ListChanged is from the Inherited class
RaiseEvent ListChanged(ThatList, Nothing)
End Sub
Private Sub ToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles ToolStripMenuItem.Click
Dim rT As New Threading.Thread(AddressOf ListenerThread)
rT.Start()
End If
End Sub
Private Sub ListenerThread()
r = New RequestListener()
*r.Listen()*
End Sub
In asterisks, this was the key element. Originally, it was called from the inherited class' constructor. This meant there was never a return to the GUI, and my class level variable was never updated. Therefore, any references to RequestListener (specifically the Events) wouldn't trigger because RequestListener is Nothing. Calling it from the GUI solved the r IS Nothing issue.
I discovered this by creating a button to raise the event manually, but was greeted with NullReferenceException. Once I started my listener from my GUI, the method handling my custom event was fired. I assume this solves my problem, but will need to work a bit more.
Facing an issue while accessing declared event in vb.net.
Please go thorough below example. (I have modified below stuff to make understable as it is part of one of custom control development)
Public Class Main
Inherits ComboBox
'Event handler for when an item check state changes.
Public Event ItemCheck As ItemCheckEventHandler
Private parentMainClass As Main
Private cclb As controlClass
Public Sub New(parentclass As Main)
Me.parentMainClass = parentclass
'Add a handler to notify our parent of ItemCheck events.
AddHandler Me.cclb.ItemCheck, New System.Windows.Forms.ItemCheckEventHandler(AddressOf Me.cclb_ItemCheck)
End Sub
Private Sub cclb_ItemCheck(sender As Object, e As ItemCheckEventArgs)
'If ccbParent.ItemCheck IsNot Nothing Then
RaiseEvent parentMainClass.ItemCheck(sender,e)
'End If
End Sub
Public Class controlClass
Inherits CheckedListBox
End Class
End Class
Problem: RaiseEvent parentMainClass.ItemCheck(sender,e) this statement shows - ItemCheck event not exists even though it is existed.
Please guide.
Thank You
The event declaration;
Public Event ItemCheck As ItemCheckEventHandler
Should be;
Public Event ItemCheck(sender As Object, e As ItemCheckEventArgs)
What the error is telling you is that it cannot match up the event to the event handler signature.
From your original code, the line;
RaiseEvent parentMainClass.ItemCheck(sender, e)
should be changed to;
RaiseEvent ItemCheck(sender, e)
This raises the ItemCheck event from the current instance. What you seem to be wanting to do is to raise the event on the parent instance, which is a bit different.
I need some help getting my head wrapped about instances and classes. In the code below I have a main_form, and I am also loading a user_control into the main_form. I have a property that resides inside main_form that I will be setting data called obj. My question is when I am doing work inside of the user_control, how can I reach in and set the obj property of main_form. I tried main_form.obj but I keep getting the error "object reference not set to an instance of an object". So, I'm not sure how to do it. Here's the dumbed down code
Public Class FormControlClass
Private _obj As New objCollection
Public Property obj As objCollection
Get
Return _obj
End Get
Set(ByVal value As objCollection)
_obj = value
End Set
End Property
'Load User Control Into Form from here.
me.controls.add('UserControl')
End Class
Public Class UserControlClass
'Access the obj property in the form control class from here.
FormControlClass.obj = 1
End Class
Even if you could do what you are trying to do, it would be a bad idea, because you would be coupling your user control to this particular form, making it useless outside of this form.
Instead you need to have your user control generate an event that the form can subscribe to and handle itself. In other words, you want to make the user control create a message that can be delivered to the form, like this:
Public Class UserControlClass
' Define event that will be raised by user control to anyone interested in handling the event
Public Event UC_Button1Click()
' Mechanism to allow event to be raised by user control
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
RaiseEvent UC_Button1Click()
End Sub
End Class
Now in your form class, you need to add a handler for the event raised by the user control, like this:
AddHandler userControl1.UC_Button1Click, AddressOf Button1_Click
Finally, you would create the method that is referenced in the AddressOf syntax, like this:
Public Sub Button1_Click(ByVal sender As Object, ByVal args As EventArgs)
' Do something here
End Sub
I have a form in VB.NET that is used as a dialog in a mainform. Its instances are always locally defined, there's no field for it. When the user clicks the OK button in the dialog, it will fire an event with exactly one argument, an instance of one of my classes.
Since it is always a local variable, how can I add an event handler for that event? I've searched for myself and found something but I can't really figure it out...
Code for the event, a field in MyDialog:
public Event ObjectCreated(ByRef newMyObject as MyObject)
Code for the main form to call dialog : (never mind the syntax)
Dim dialog As New MyDialog()
dialog.ShowDialog(Me)
AddHandler ObjectCreated, (what do I put here?) //Or how do I add a handler?
As you can see I'm stuck on how to add a handler for my event. Can anyone help me? Preferrably with the best way to do it...
It's recommended, for consistency, that you use the same source and event args model as all system event handlers.
Create your own class inheriting from EventArgs, as:
Public Class MyObjectEventArgs
Inherits EventArgs
Public Property EventObject As MyObject
End Class
Then declare your event, and a handler method, like:
Public Event ObjectCreated As EventHandler(Of MyObjectEventArgs)
Private Sub Container_ObjectCreated(ByVal sender As Object, ByVal e As MyObjectEventArgs)
' Handler code here
End Sub
Then attach the handler to your event using:
AddHandler ObjectCreated, AddressOf Container_ObjectCreated
Additionally, you can use the Handles to attach to the event raised from your main form (assuming the name MainForm), as below:
Private Sub MainForm_ObjectCreated(ByVal sender As Object, ByVal e As MyObjectEventArgs) Handles MainForm.ObjectCreated
' Handler code here
End Sub
You need to write the subroutine that actually executes when the event is generated:
public Sub OnObjectCreated(ByRef newMyObject as MyObject)
...
End Sub
Then the handler is added:
AddHandler ObjectCreated, AddressOf OnObjectCreated
As a side note, ByRef does nothing here. All objects in VB are passed by reference. Only primitave variables (string, int, etc) by default use ByVal and can be set to ByRef