在vb.net中如何引发另一个控件的事件

时间:2014-01-07 17:08:48

标签: vb.net events

我看到的每个样本都是指鼠标点击,然后示例是相同的。

我需要专门针对另一个控件举起一个事件。

我有一个面板,其中包含我创建的事件:

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

因此,当垂直滚动条移动时,“更改”事件将触发。

所以现在,我有另一个控件,(一个简单的面板)设置如下:

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

那么,如何从view_Panel中激活“更改”事件?

3 个答案:

答案 0 :(得分:0)

修改 要从另一个类调用您的事件,您可以使用反射

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

答案 1 :(得分:0)

你可能想要这样的东西:

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是一个标准的Net事件,所以我们不需要定义它。然后将事件声明为('更改'似乎是一个非常糟糕的选择):

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

如果您的Panel需要对事件执行某些操作,请使用OnScroll方法,该方法允许面板在最终订阅者获取事件之前执行操作:

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

使用方法:

由于你是两者的子类,让Panel引发事件,FlowPanel可以监视这些事件(订阅面板的scroll事件),然后在Change中执行你要做的任何事情。由于ACTION在面板中/面板上进行,因此最好只在那里进行处理。

答案 2 :(得分:0)

即使在阅读了上面的“Pouya Samie”之后的其他答案(反映给OnChange,如果可用的话),或者这个更加强化的文章“Raising Events Using Reflection”似乎更清洁但并不总是有效(反映到MulticastDelegate)......

所以最后我想把所有的想法都放在泛型方法中,用简单的语法来执行这个任务:

TriggerEvent(ComboBox1, "OnSelectedIndexChanged")

请注意,上述方法在ComboBox1中是私有不可访问,在IntelliSense列表成员上甚至未列出,但使用此反射方法,它将起作用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