代码之家  ›  专栏  ›  技术社区  ›  Paul Sasik

如何处理来自其他类/实例的成员的事件

  •  2
  • Paul Sasik  · 技术社区  · 14 年前

    我正在尝试在应用程序的几个不同部分之间共享一个子菜单,以便它是一致的(不想复制/粘贴)。我在做这样的事情:

     public class MyClientClass
         Private WithEvents ctx As ContextMenuManager = New ContextMenuManager
         Private Sub handler() Handles ctx._myToolstripMenuItem.Click
             ' do something useful
        End Sub
    End Class
    
    Public Class ContextMenuManager
        Public WithEvents _myToolstripMenuItem As ToolStripMenuItem
    
        Public Sub New()
            Me._myToolstripMenuItem = New ToolStripMenuItem
            Me._myToolstripMenuItem.Name = "DoSomehting"
            Me._myToolstripMenuItem.Size = New System.Drawing.Size(48, 20)
            Me._myToolstripMenuItem.Text = "Go!"
        End Sub
    End Class
    

    但这段代码给了我一个错误:类中的“Handles”必须指定一个“WithEvents”变量、“MyBase”、“MyClass”或“me”,并用单个标识符限定。

    换了个方法来解决这个问题。处理共享类中的所有事件并使用公共对象触发公共事件:

    Private Sub MenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) _
     Handles ToolStripMenuItem.Click
         ' edit _legacyAttributes instance per specifics
         ' ...
         ' then always raise the same event with the updated payload object
         RaiseEvent TypeChanged(_legacyAttributes)
     End Sub
    

    因此,您可以想象,在类中有几十个这样的处理程序,每个处理程序都在合理地修改其\u legacyAttribute。。。

    3 回复  |  直到 5 年前
        1
  •  1
  •   Hans Passant    14 年前

    不允许额外的间接操作。您必须这样编写ContextMenuManager类:

    Public Class ContextMenuManager
        Public Event Click As EventHandler
        Private WithEvents _myToolstripMenuItem As ToolStripMenuItem
    
        Public Sub New()
            ''...
        End Sub
    
        Private Sub _myToolstripMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles _myToolstripMenuItem.Click
            RaiseEvent Click(Me, e)
        End Sub
    End Class
    

        2
  •  2
  •   supercat    14 年前

    “withevents”声明是一种非常好的语法糖分,类似于:

    WithEvents Foo as Control 
      -- becomes
    Dim _Foo as Control
    Property Foo as Control
      Get
        Return _Foo
      End Get
      Set(Value as Control)
        If _Foo IsNot Nothing Then
          RemoveHandler _foo.Click,foo_Click
          RemoveHandler _foo.Load,foo_Load
          etc.
        End If
        _Foo = Value
        If _Foo IsNot Nothing Then
          AddHandler _foo.Click,foo_Click
          AddHandler _foo.Load,foo_Load
          etc.
        End If
      End Set
    End Property
    

        3
  •  0
  •   Paul Sasik    14 年前

    Handles ctx._myToolstripMenuItem.Click
    

    在加载事件或某些初始方法中,我将执行以下操作:

    AddHandler ctx._myToolstripMenuItem.Click, AddressOf handlerMethod