Избегать дублированных обработчиков событий? - PullRequest
3 голосов
/ 22 марта 2011

Как избежать обработки события дважды (если это один и тот же обработчик?)

Module Module1
  Sub Main()
    Dim item As New Item
    AddHandler item.TitleChanged, AddressOf Item_TitleChanged
    AddHandler item.TitleChanged, AddressOf Item_TitleChanged

    item.Title = "asdf"

    Stop
  End Sub
  Private Sub Item_TitleChanged(sender As Object, e As EventArgs)
    Console.WriteLine("Title changed!")
  End Sub
End Module

Public Class Item
  Private m_Title As String
  Public Property Title() As String
    Get
      Return m_Title
    End Get
    Set(ByVal value As String)
      m_Title = value
      RaiseEvent TitleChanged(Me, EventArgs.Empty)
    End Set
  End Property

  Public Event TitleChanged As EventHandler
End Class

Вывод:

Title changed!
Title changed!

Желаемый вывод:

Title changed!

Я хочу, чтобы менеджер событий обнаружил, что это событие уже обработано этим обработчиком, и поэтому он не должен обрабатывать (или читать) его.

Ответы [ 2 ]

6 голосов
/ 22 марта 2011

Вы также можете просто позвонить RemoveHandler до AddHandler.Я нашел это практичным в определенных сценариях.

0 голосов
/ 22 марта 2011

Оборачивая список обработчиков событий в HashSet, вы убедитесь, что обработчики не являются повторяющимися ссылками, следующий фрагмент кода для класса Item вопроса будет работать в приведенном выше примере (он не будет повторно добавлять обработчик) если это уже в HashSet):

Public Class Item
  Private m_Title As String
  Public Property Title() As String
    Get
      Return m_Title
    End Get
    Set(ByVal value As String)
      m_Title = value
      RaiseEvent TitleChanged(Me, EventArgs.Empty)
    End Set
  End Property

  Private handlers As New HashSet(Of EventHandler)

  Public Custom Event TitleChanged As EventHandler
    AddHandler(value As EventHandler)
      handlers.Add(value)
    End AddHandler

    RemoveHandler(value As EventHandler)
      handlers.Remove(value)
    End RemoveHandler

    RaiseEvent(sender As Object, e As System.EventArgs)
      For Each handler In handlers.Where(Function(h) h IsNot Nothing)
        handler(sender, e)
      Next
    End RaiseEvent
  End Event
End Class
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...