What is the optimal approach to a WithEvents
Collection
- VB.NET?
Have you any remarks on the code bellow (skipping the Nothing
verifications)?
The problem is when I obtain the LinkedListNode(Of Foo)
in a For Each
block I can set
myNode.Value = something
, and here is a handlers leak...
-Could I override the FooCollection's GetEnumerator
in this case?
NotInheritable
Class LinkedListNode(Of T)
Class Foo
Public Event SelectedChanged As EventHandler
End Class
Class FooCollection
Inherits LinkedList(Of Foo)
Public Event SelectedChanged As EventHandler
Protected Overloads Sub AddFirst(ByVal item As Foo)
AddHandler item.SelectedChanged, AddressOf OnSelectedChanged
MyBase.AddFirst(item)
End Sub
Protected Overloads Sub AddLast(ByVal item As Foo)
AddHandler item.SelectedChanged, AddressOf OnSelectedChanged
MyBase.AddLast(item)
End Sub
' ------------------- '
Protected Overloads Sub RemoveFirst()
RemoveHandler MyBase.First.Value.SelectedChanged, _
Addr开发者_运维知识库essOf OnSelectedChanged
MyBase.RemoveFirst()
End Sub
Protected Overloads Sub RemoveLast(ByVal item As Foo)
RemoveHandler MyBase.Last.Value.SelectedChanged, _
AddressOf OnSelectedChanged
MyBase.RemoveLast()
End Sub
' ------------------- '
Protected Sub OnSelectedChanged(ByVal sender As Object, ByVal e As EventArgs)
RaiseEvent SelectedChanged(sender, e)
End Sub
End Class
The main problem is that you can't override the GetEnumerator function properly. In such case I would create a class that doesn't directly inherit from LinkedList but only uses one as a private field:
Class FooCollection
Implements ICollection(Of Foo)
Private list As New LinkedList(Of Foo)
Public Sub AddFirst(ByVal item As Foo)
AddHandler item.SelectedChanged, AddressOf OnSelectedChanged
list.AddFisrt(item)
End Sub
...
End Class
It will require a little more coding because you need to implement all the functions instead of just the ones you want to override but the implementation is trivial.
Have you looked at CollectionChangedEventManager
? I just ran across this today when looking to deal with queue changes.
As I understand, there is no easy solution because the collection just holds references to the ocjects and has therefore no way to know, if a property of an object the collection holds has changed.
In general you have to options:
1:) You let the objects your collection controls fire events. A sample implementation you find in this MSDN article from Charles Petzold. He defines a "ObservableNotifiableCollection".
2:) If the types the collection holds are not at your control (so you can't implement a PropertyChangedEvent yourself), you could use a proxy objects. A sample implementation you can find here: "Implement InotifyPropertyChanged with Castle.DynamicProxy".
精彩评论