Facing an issue while accessing declared event in vb.net - vb.net

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.

Related

Raising UserControl's default Click event

I've created a usercontrol.
I've placed a Button into it.
Now when I click the button, I would like to raise the default Click event.
For that, I added the following code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
RaiseEvent Click(sender, e)
End Sub
What am I doing wrong here?
This is the entire code of the usercontrol:
Imports System.ComponentModel
Public Class ucColorButton
<Browsable(True)>
Public Overrides Property BackColor() As Color
Get
Return Me.Button1.BackColor
End Get
Set(value As Color)
Me.Button1.BackColor = value
End Set
End Property
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
RaiseEvent Click(sender, e)
End Sub
End Class
The compiler tells me:
There's no RaiseEvent definition for the event "Click"
You don't use RaiseEvent to raise an inherited event. This is why all events should have an associated method. To raise the Click event you call the OnClick method and that is the only place that RaiseEvent is used. If you want to change the behaviour on a Click event then you override that method, otherwise you just accept the default behaviour from the base class. To see how events are properly implemented - and are implemented in the base classes you're inheriting - check this out.
Also, while it technically doesn't matter in this case, you shouldn't really be passing the e parameter from your internal event handler to your external event. You should be creating your own EventArgs object as required by your event.
Finally, if you were to be able to use RaiseEvent, it would be wrong to pass on the sender parameter too. The sender is ALWAYS supposed to be the object that raised the event. In your case, that is the user control, NOT the internal Button. Fortunately, calling OnClick will fix that. If you needed to pass on information about which child control was clicked then you should be defining your own event and passing that information via the e parameter.

VB.net Access class property from another class

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

Allowing Users to Handle an event in place of a default event

I am building a custom control and what i would like to do is have an event lets call this event OnMenuShow. Now what i would like to be able to do is handle this event inside my control to show one menu but allow the user implementing my custom control to handle the event in inside the parent form to show a different menu if they wish. so the users code would look something like this.
Public Sub Control_OnMenuShow(sender as Object, e as CustomEventArgs) handles Control.OnMenyShow
'DO some work
e.handled = true
end Sub
I'm just not sure on how to prevent the event from firing twice once for the code inside the control the other in the event. if someone could point me in the right direction that would be very helpful
-Nathan
In your control:
Public Event MenuShow As EventHandler
Public Overridable Sub OnMenuShow()
RaiseEvent MenuShow(New EventArgs)
End Sub
Now the consumer may override OnMenuShow which would bypass your raiseevent statement without you needing to "check" anything.
I found that Hans' answer reponse fit my question the best, and had he left it in an answer I would have marked his as answered. I will leave how I ended up coding this for future refrence.
Public Event MenuShow As EventHandler(Of MenuShowEventArgs)
Public Overridable Sub OnMenuShowEvent()
Dim args As New MenuShowEventArgs(False, "Control")
RaiseEvent MenuShow(Me, args)
if args.handled then return
'DO WORK
End Sub

How to add event handler to local variable in VB.NET

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

How do you handle an event raised in your class inside your own class?

I have a "partial" class in VB.NET. Half of it is auto generated by a code generation tool. That half implements INotifyPropertyChanged, so any properties in that part of the partial class raise the PropertyChanged event.
In my "custom" part of the class, I declare another property that depends on one of the properties in the auto-generated side. Therefore, when that auto-generated property changes, I also want to raise a PropertyChanged event on my custom property that depends on it.
If I go into the generated part of the class and raise the event there, that will get overwritten if I ever re-generate that part, so I don't want to do that. I would rather add an event handler in my side of the partial class that checks if the generated property changed, and if so, raise another event for my custom property.
I'm trying to write this to hook my own event, but it's not working:
Private Sub MyProperty_PropertyChangedHandler( _
ByVal sender As Object, ByVal e As PropertyChangedEventArgs _
) Handles Me.PropertyChanged
Select Case e.PropertyName
Case "AutoGenProperty"
RaiseEvent PropertyChanged(Me, _
New PropertyChangedEventArgs("MyProperty"))
End Select
End Sub
I'm assuming it's because normally you'd use the WithEvents keyword to tell the compiler that you're subscribing to events from that object. I don't have a clue how to do this inside of the class that's actually raising the event, or if that's even possible.
In your constructor, you need something on the lines of
AddHandler PropertyChanged, addressof MyProperty_PropertyChangedHandler
and remove the "Handles Me.PropertyChanged" from your event handler, basically your adding the event handler manually
where "PropertyChanged" is the name of the event you want to catch.
UPDATE
You can't do that because the the ctor is in the auto generated portion of the class.
So you can use the following idiom to add the handler for you.
You're going to specify a private class inside your class, and put it on as a private member on your new class, when the private member is constructed you add the handler for the event.
Public Partial MyClass
private class MyInitialiser
public sub new(byval myParent as MyClass)
Addhandler myParent.PropertyChanged, addressof myParent.MyProperty_PropertyChangedHandler
end sub
end class
private _myInitialiser as new MyInitialiser(me)
. . .
End Class
The above is untested, but I've done this lots of times before.
Hope it helps :)