2013-09-21 47 views
2

在Visual Basic.net中,是否可以向T列表中添加事件處理程序,以便每當列表發生更改時,都會調用此事件?爲列表添加事件處理程序

例如,如果我有一個稱爲Schedule的類,並且此Schedule具有ScheduleItem的List,那麼如何添加一個將在此List更改時被調用的事件?

回答

2

當列表發生變化時會引發事件的集合(一個爲​​),但事件只會在列表所在的類/表單中可用。對於更廣泛的實施,您的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下拉列表中選擇新的條目腹肌相關事件:

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.ScheduleSomeOtherClass需要了解該事件。在這種情況下,Schedule仍生成事件,Foo訂閱它,然後引發自己的ScheduleChanged事件,傳遞事件參數。其他演員訂閱事件上Foo。這被稱爲「冒泡」事件。


你還可以創建一個小班有一個方法,所以沒有任何比引發事件更多。在這種情況下,它將由Schedule創建,並通過非私人成員提供給任何演員。 SomeOtherClass可以參考Foo的Schedule.ScheduleChangeNotifier。當列表更改時,Schedule將調用引發事件的方法,並且不涉及Foo。

這種模式通常被稱爲EventBus,但它可以被看作是一個廣播,接收器設置:計劃使用類廣播通知,其他人用它來接收它們作爲一個事件。當兩個演員甚至不需要相互瞭解時,這是有用的。

一個例子是Foo.Bar需要了解從Fizz.Blorg東西:Bar可以接收這些事件不涉及FizzFoo超越上車/通知對象Bar

它比冒泡事件不太常見,但有時非常有用的。通常但如果它似乎是答案,我試着重新審視設計,看東西可以簡化。

0

List(Of)不提供此開箱即用。

您可以創建自己的實現IList(Of)並實施您想要的事件,也可以使用現有集合,如BindingList(Of)ObservableCollection(Of)

相關問題