为列表添加事件处理程序



在Visual Basic.net 中,是否可以将事件处理程序添加到 T 列表,以便每当列表更改时,都会调用此事件?

例如,如果我有一个名为 Schedule 的类,并且此 Schedule 有一个 ScheduleItem 列表,那么如何添加在更改此列表时将调用的事件?

有些集合会在列表更改时引发事件(BindingList(of T)一个),但事件仅适用于列表所在的类/窗体。 对于更广泛的实现,Schedule类可以引发事件。

  1. 确保只有Schedule对列表进行更改。 也就是说,您的List(Of T)应该是私有成员。 其他对象应通过它进行更改,以便它完全了解所有更改,从而不会遗漏任何更改。

  2. 确定什么是变更事件。 添加和删除项目是显而易见的,但根据ScheduleItem中的内容,.StartTime或类似的属性也可能是事件。(这实际上需要对项目类进行INotifyPropertyChanged

  3. 对于"添加和删除",每次Schedule内部列表中添加或删除项目时,它都会引发事件以通知订阅者。

  4. 谁将消费(或获取)这些事件? 形式? 其他类结构?

一个简单的方法,一旦在"拥有"列表的类中发生所有更改,就是一个自定义事件:

Public Class Schedule
    Private MyList as List (Of ScheduleItem)
    Public Event ScheduleChanged(sender As Object, e As EventArgs)
     ...
   Public Sub AddItemToSchedule(....)
      ' I have no idea what is in a ScheduleItem....
      ...
      MyList.Add(si)
      ' the point is that if it gets added / not a dupe etc, then:
      ' tell any subscribers that the sched changed:
       RaiseEvent ScheduleChanged(Me, New EventArgs())
   End Sub
   Public Sub RemoveItem(...)
       ' do whatever to remove an item
       ' ... 
       MyList.Remove(si)
       ' tell subscribers the sched changed
       RaiseEvent ScheduleChanged(Me, New EventArgs())
   End Sub
End Class

私人收藏的另一种方法是让Schedule继承类似的东西 Collection(of T) . 对于活动的订阅者:

Public Class SomeOtherClass
    ' These need a reference to the Schedule object
    Private WithEvents Sched As Schedule
    ...
    Public Sub New(scObj As Schedule)
        Sched = scObj
    End Sub
End Class

SomeOtherClass现在将在左侧 VS 下拉列表中有一个新条目 abs 相关事件:

Private Sub Sched_ScheduleChanged(sender As Object,
                  e as EventArgs) Handles Sched.ScheduleChanged
     ' add code here to respond to schedule changes
End Sub

用法:

Dim foo = New SomeOtherClass(SchedObj)

创建 SomeOtherClass 对象的任何内容都会在构造函数中传递Schedule对象。 如果它是由Schedule创建的,它将是 Me .

如果SomeOtherClass有权访问Schedule则可以放弃构造函数参数:

Public Sub New()
    Sched = mainSchedInstance
End Sub

在所有情况下Schedule都需要存在,否则代码将尝试挂接到Nothing对象上的事件。

笔记

  • 在所有事件中传递Sched对象(Me)似乎很奇怪(还有谁会发送ScheduleChanged事件? 但是 VS 代码分析工具反对 Object sender, EventArgs e 以外的事件签名。
  • 如果要在事件中传递诸如更改类型之类的信息,请创建一个继承自EventsArgs的类,并添加所需的任何属性。 其中之一可能是添加ScheduleItem

还有其他方法可以实现这一点,例如它是Foo.Schedule的,SomeOtherClass需要了解该事件。 在这种情况下,Schedule 仍会生成事件,Foo订阅它,然后引发自己的ScheduleChanged事件,传递事件参数。 其他演员在Foo上订阅了该事件。 这被称为"冒泡"事件。


您还可以使用一种方法创建一个小类,并且只执行引发事件。在这种情况下,它将由Schedule创建,并通过非私有成员提供给任何参与者。 SomeOtherClass可以从Foo那里获得对Schedule.ScheduleChangeNotifier的引用。 当列表更改时,Schedule调用触发事件的方法,并且不涉及 Foo。

此模式通常称为 EventBus,但可以将其视为广播接收器设置:调度使用该类广播通知,其他人使用它将其作为事件接收。 当两个参与者甚至不需要相互了解时,它很有用。

一个例子是Foo.Bar需要从Fizz.Blorg知道一些东西:Bar可以接收这些事件,而不涉及FizzFoo,除了让总线/通知器对象Bar

它比冒泡事件少见,但有时非常有用。 通常,如果看起来这就是答案,我会尝试重新检查设计,看看是否可以简化。

List(Of )没有

提供开箱即用的功能。

您可以创建自己的IList(Of )实现并实现所需的事件,也可以使用现有集合(如 BindingList(Of )ObservableCollection(Of ) )。

相关内容

  • 没有找到相关文章