.net - 为列表添加事件处理程序

标签 .net vb.net list event-handling

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

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

最佳答案

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

  • 确保只有 Schedule对列表进行更改。也就是说,您的 List(Of T)应该是私有(private)成员(member)。其他对象应该通过它进行更改,以便它完全了解所有更改,以免错过任何更改。
  • 确定什么是变更事件。添加和删​​除项目是显而易见的,但取决于 ScheduleItem 中的内容也许 .StartTime或类似的属性也是事件。 (这实际上需要在项目类别上使用 INotifyPropertyChanged)
  • 只需添加和删除,每次Schedule从内部列表中添加或删除项目,它会引发事件以通知订阅者。
  • 谁将消费(或获取)这些事件?形式?其他类结构?

  • 一个简单的方法是,一旦所有更改都发生在“拥有”列表的类中,就是一个自定义事件:
    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 可以替代私有(private)收藏。从 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现在将在 Left VS Dropdown 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需要存在,否则代码将尝试 Hook Nothing 上的事件目的。

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

  • 还有其他方法可以实现,例如 Foo.ScheduleSomeOtherClass需要了解事件。在这种情况下,Schedule 仍会生成事件 Foo订阅它然后引发它自己的ScheduleChanged事件,传递事件参数。其他参与者订阅 Foo 上的事件.这被称为“冒泡”事件。

    您还可以使用一种方法创建一个小类,只做一个事件。在这种情况下,它将由 Schedule 创建。并且可以通过非私有(private)成员提供给任何 Actor 。 SomeOtherClass可以引用 Schedule.ScheduleChangeNotifier来自福。当列表发生变化时,Schedule调用触发事件的方法并且 Foo 不参与。

    这种模式通常称为 EventBus,但可以将其视为 Broadcast-Receiver 设置:Schedule 使用该类广播通知,其他人使用它作为事件接收它们。当两个 Actor 甚至不需要彼此了解时,它很有用。

    一个例子是 Foo.Bar需要从 Fizz.Blorg 了解一些事情: Bar可以在不涉及 Fizz 的情况下接收这些事件或 Foo除了将总线/通知器对象发送到 Bar .

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

    关于.net - 为列表添加事件处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18929796/

    相关文章:

    .net - Winforms WebBrowser 告诉何时完成刷新

    Python - 如何将多维列表排序为二维列表?

    .net - WCF HTTP POST 给出 HTTP 状态代码 400 : Bad Request

    .net - 创建泛型类型的泛型列表

    c# - 命令行解析器库 .NET 能够检索版本号

    VB.NET 本地化

    python - 在列表上使用求和函数时,“int”对象不可调用

    python - 连接对象列表中的字符串

    c# - 使用 .Net 4.0 时出现 PInvoke StackImbalance 错误,但使用 .Net 2.0 时则不会

    .net - 如何克隆 .NET 解决方案?