Visual Basic.net では、イベント ハンドラーを T のリストに追加して、リストが変更されるたびにこのイベントが呼び出されるようにすることはできますか?
たとえば、Schedule というクラスがあり、この Schedule に ScheduleItem のリストがある場合、このリストが変更されるたびに呼び出されるイベントを追加するにはどうすればよいですか?
Visual Basic.net では、イベント ハンドラーを T のリストに追加して、リストが変更されるたびにこのイベントが呼び出されるようにすることはできますか?
たとえば、Schedule というクラスがあり、この Schedule に ScheduleItem のリストがある場合、このリストが変更されるたびに呼び出されるイベントを追加するにはどうすればよいですか?
リストが変更されたときにイベントを発生させるコレクションがありますが ( BindingList(of T)
1 つ)、イベントはリストが存在するクラス/フォームでのみ使用できます。より広範な実装のために、Schedule
クラスはイベントを発生させることができます。
リストのみSchedule
を変更するようにしてください。つまりList(Of T)
、プライベート メンバーである必要があります。他のオブジェクトは、すべての変更を完全に認識して見逃さないように、それを介して変更を行う必要があります。
変更イベントとは何かを決定します。アイテムの追加と削除は明らかですが、ScheduleItem
多分.StartTime
または同様のプロパティの内容によっては、イベントも同様です。(実際INotifyPropertyChanged
にはアイテムクラスで必要になります)
Add と Delete の場合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
ようなものから継承することです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 abs a related event に新しいエントリが追加されます。
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 コード分析ツールは、.NET 以外のイベント シグネチャに反対しObject sender, EventArgs e
ます。EventsArgs
必要なプロパティを追加します。それらの1つはScheduleItem
追加される可能性がありますFoo.Schedule
これを実装する方法は他にもあります。たとえばSomeOtherClass
、イベントについて知る必要がある場合などです。この場合でも、Schedule はイベントを生成し、Foo
サブスクライブしてから、独自のScheduleChanged
イベントを発生させ、イベント引数を渡します。他のアクターは のイベントにサブスクライブしFoo
ます。これは、イベントの「バブルアップ」と呼ばれます。
また、イベントを発生させるだけで、メソッドが 1 つの小さなクラスを作成することもできます。この場合、それはSchedule
非プライベート メンバーを介して任意のアクターによって作成され、利用可能になります。 from FooSomeOtherClass
への参照を取得できます。Schedule.ScheduleChangeNotifier
リストが変更さSchedule
れると、イベントを発生させるメソッドが呼び出され、Foo は関与しません。
通常、このパターンは EventBus と呼ばれますが、Broadcast-Receiver セットアップと考えることができます。Schedule はクラスを使用して通知をブロードキャストし、他のクラスはそれを使用してそれらをイベントとして受信します。2 つのアクターが互いのことを知る必要がない場合に便利です。
例としてFoo.Bar
、 から何かを知る必要がある場合がありFizz.Blorg
ます。これらのイベントは、バス/通知オブジェクトを に取得することを必要とBar
せずに受け取ることができFizz
ます。Foo
Bar
イベントをバブリングするほど一般的ではありませんが、非常に役立つ場合があります。通常、それが答えだと思われる場合は、設計を再検討して、単純化できないかどうかを確認します。
List(Of )
これはそのままでは提供されません。
独自の実装を作成して必要なイベントを実装するか、またはIList(Of )
のような既存のコレクションを使用することができます。BindingList(Of )
ObservableCollection(Of )