John
John

Reputation: 1338

in vb.net how do I raise an event of another control

Every sample I've seen that refers to this is about mouse clicks and then the example is the same.

I need to specifically raise an event on another control.

I have a panel with an event that I created like this:

Private FlowPanel as new my_FlowLayoutPanel
Addhandler FlowPanel.change, addressof doChange

    Public Class my_FlowLayoutPanel
            Inherits FlowLayoutPanel

            Public Event change(ByVal sender As Object)
            Public Const Ver_SCROLL As Integer = &H115

            Protected Overrides Sub WndProc(ByRef m As Message)
                If m.Msg = Ver_SCROLL Then
                    RaiseEvent change(Me)
                End If

                MyBase.WndProc(m)
            End Sub
        End Class

So when the vertical scroll bar moves, the "change" event fires.

So now, I have another control, (a simple panel) set up like this:

Public Class view_Panel
        Inherits System.Windows.Forms.Panel

        Protected Overrides Sub WndProc(ByRef m As Message)

            Const NCMOUSEMOVE As Integer = &H200

            If m.Msg = NCMOUSEMOVE Then

              ' *** FIRE THE "CHANGE" EVENT ON THE FLOWLAYOUT PANEL

            End If
            MyBase.WndProc(m)
        End Sub

    End Class

So, how do I fire the "Change" event from the view_Panel?

Upvotes: 1

Views: 2890

Answers (3)

JCM
JCM

Reputation: 570

Even after reading other answers such as 'Pouya Samie' above (reflect to OnChange if available), or this more enhanced article "Raising Events Using Reflection" which seems much cleaner but doesn't always work (reflect to MulticastDelegate)...

So finally got to put all my ideas in order for a generic method to perform this task with a simple syntax:

TriggerEvent(ComboBox1, "OnSelectedIndexChanged")

Notice that the above method is private non-accesible inside the ComboBox1, it is even NOT listed on the IntelliSense list members, but with this reflection method it will work OK:

''' <summary>
''' Manually trigger an existing event in a control.
''' </summary>
''' <param name="ctrlObject">The GUI control that that should be operated (such as ComboBox).</param>
''' <param name="onEventName">The OnEvent function regardless of the scope (such as OnSelectedIndexChanged).</param>
''' <returns><code>True</code> when the method is found invoked and returned successfully; <code>false</code> otherwise.</returns>
Public Function TriggerEvent(ctrlObject As Control, onEventName As String) As Boolean

    ' Get the reference to the method
    Dim methodRef As MethodInfo = ctrlObject.GetType().GetMethod(onEventName, _
            System.Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Public Or Reflection.BindingFlags.Static Or _
            System.Reflection.BindingFlags.Instance)
    If IsNothing(methodRef) Then Return False

    ' Invoke the method
    Try
        methodRef.Invoke(ctrlObject, New Object() {EventArgs.Empty})
        Return True
    Catch ex As Exception
        Return False
    End Try

End Function

Upvotes: 2

You probably want something like this:

Case WM_HSCROLL
     RaiseEvent Scroll(Me, New ScrollEventArgs(ScrollEventType.EndScroll, _
           Win32.GetScrollPos(Me.Handle, Win32.SBOrientation.SB_HORZ), _ 
           ScrollOrientation.HorizontalScroll))

Case WM_VSCROLL
     RaiseEvent Scroll(Me, New ScrollEventArgs(ScrollEventType.EndScroll, _
           Win32.GetScrollPos(Me.Handle, Win32.SBOrientation.SB_VERT), _
           ScrollOrientation.VerticalScroll))

ScrollEventArgs is a standard Net event, so we dont need to define it. Then declare the event as ('change' seems a very poor choice):

Public Event Scroll(ByVal sender As Object, ByVal sa As ScrollEventArgs)

If your Panel needs to do something with the event, use the OnScroll method, which allows the panel to do stuff before the end subscriber gets the event:

Protected Overrides Sub OnScroll(ByVal sa As ScrollEventArgs)
    ... do stuff
    ' in cases where you no longer need the event to be passed
    ' on, dont call this:
    MyBase.OnScroll(e)
End Sub

How to use:

Since you subclass both, let the Panel raise the event, the FlowPanel can monitor those events (subscribe to the panel's scroll event) and in that, do whatever you were going to do in Change. Since the ACTION takes place in/on the panel, better to just handle it there.

Upvotes: 0

Pouya Samie
Pouya Samie

Reputation: 3723

EDIT To Call your Event From Another Class you can use reflection

 MethodInfo onchange = YourClassInstance.GetType().GetMethod("OnChange",              System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
    onChange.Invoke(YourClassInstance, new object[] { new EventArgs() });

Upvotes: 1

Related Questions