Как обрабатывать события членов из другого класса / экземпляра - PullRequest
2 голосов
/ 14 июля 2010

Я пытаюсь разделить подменю между несколькими различными частями приложения, чтобы оно было согласованным (не желая копировать / вставлять). Я подумал, что это будет просто.Я делаю что-то вроде этого:

 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

Но этот код дает мне сообщение об ошибке: «Дескрипторы» в классах должны указывать переменную «WithEvents», «MyBase», «MyClass» или «Me» с квалификациейединственный идентификатор.

Я предоставил ключевое слово WithEvents как для приложения контейнера, так и для пункта меню.Что дает?Что мне не хватает?Может ли пример C # выдать ту же ошибку?

Изменен фокус, чтобы решить эту проблему другим способом.Обработка всех событий в совместно используемом классе и запуск общего события с помощью общего объекта:

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

Итак, вы можете представить, что в классе есть десятки подобных обработчиков, каждый из которых изменяет свои _legacyAttributes так, как онимеет смысл ...

Ответы [ 3 ]

2 голосов
/ 30 октября 2010

Декларация "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

Будет один RemoveHandler и один AddHandler для каждого объявления Handles, связанного с Foo. Обратите внимание, что такие объявления свойств могут быть сделаны только внутри существующего класса. У класса нет общего способа сообщить другому классу, что установка одного из его свойств должна привести к подписке на события от имени предыдущего класса.

1 голос
/ 14 июля 2010

Дополнительное косвенное обращение не допускается.Вам нужно написать класс 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

Теперь вы можете использовать «Handles _ctx.Click».Конечно, есть смысл скрывать детали реализации ContextMenuManager, поэтому дополнительный код вполне может стоить того.Да, AddHandler не имеет этого ограничения.

0 голосов
/ 14 июля 2010

Не могу найти ответ, почему синтаксис Handles не работает, но я нашел обходной путь OK, используя AddHandler для прикрепления событий.Поэтому вместо:

Handles ctx._myToolstripMenuItem.Click

В случае загрузки или какого-либо начального метода я сделаю:

AddHandler ctx._myToolstripMenuItem.Click, AddressOf handlerMethod
...