|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
How to Handle clsMyClass.Event raised in GenericList(Of clsMyClass)Hi,
I have a Generic List, for instance: Public MyPersonnesDeContact As New System.Collections.Generic.List(Of clsPersonne) My clsPersonne raises some events, and I want to be able to handle these events. The problem is: when using the WithEvents (Public WithEvents MyPersonnesDeContact As New System.Collections.Generic.List(Of clsPersonne)) I get an error, saying "'WithEvents' variable does not raise any events.". Does anybody know how I could be able to handle events that happens in the intances of the class in my Generic.List? Any help, hints, workarounds etc would be really appreciated! Thanks a lot in advance, Pieter Pieter,
Are you sure that your class raises "Public" events. Fist guess :-) Corhehe yes I'm sure. I can do this "Public WithEvents clsP As New clsPersonne"
without any problem... Show quote "Cor Ligthert [MVP]" <notmyfirstn***@planet.nl> wrote in message news:%23huyOE%23zFHA.3896@TK2MSFTNGP10.phx.gbl... > Pieter, > > Are you sure that your class raises "Public" events. > > Fist guess > > :-) > > Cor > One way is that before inserting the objects in generic list, hook up the
event handlers. ---------------- -Atul, Sky Software http://www.ssware.com Shell MegaPack For .Net & ActiveX Windows Explorer GUI Controls & Quick-Launch Like Appbars, MSN/Office2003 Style Popups, System Tray Icons and Shortcuts/Internet Shortcuts ---------------- Show quote "DraguVaso" <pietercou***@hotmail.com> wrote in message news:e5MjPA%23zFHA.2924@TK2MSFTNGP15.phx.gbl... > Hi, > > I have a Generic List, for instance: Public MyPersonnesDeContact As New > System.Collections.Generic.List(Of clsPersonne) > > My clsPersonne raises some events, and I want to be able to handle these > events. The problem is: when using the WithEvents (Public WithEvents > MyPersonnesDeContact As New System.Collections.Generic.List(Of > clsPersonne)) I get an error, saying "'WithEvents' variable does not raise > any events.". > > Does anybody know how I could be able to handle events that happens in the > intances of the class in my Generic.List? > > Any help, hints, workarounds etc would be really appreciated! > > Thanks a lot in advance, > > Pieter > > Hi,
Try something like this. Public Class Form1 Dim myList As New List(Of TestClass) Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load For x As Integer = 0 To 10 Dim ct As New TestClass ct.TestItem = x.ToString AddHandler ct.ItemAdded, AddressOf ItemAddedEvent myList.Add(ct) Next End Sub Public Sub ItemAddedEvent(ByVal sender As Object, ByVal e As EventArgs) MessageBox.Show("Item Added") End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click myList(5).TestItem = "Changed" End Sub End Class Public Class TestClass Public Event ItemAdded(ByVal sender As Object, ByVal e As EventArgs) Dim mstrTest As String Public Property TestItem() As String Get Return mstrTest End Get Set(ByVal value As String) mstrTest = value RaiseEvent ItemAdded(Me, New EventArgs) End Set End Property End Class Ken ------------------- Show quote "DraguVaso" <pietercou***@hotmail.com> wrote in message news:e5MjPA%23zFHA.2924@TK2MSFTNGP15.phx.gbl... > Hi, > > I have a Generic List, for instance: Public MyPersonnesDeContact As New > System.Collections.Generic.List(Of clsPersonne) > > My clsPersonne raises some events, and I want to be able to handle these > events. The problem is: when using the WithEvents (Public WithEvents > MyPersonnesDeContact As New System.Collections.Generic.List(Of > clsPersonne)) I get an error, saying "'WithEvents' variable does not raise > any events.". > > Does anybody know how I could be able to handle events that happens in the > intances of the class in my Generic.List? > > Any help, hints, workarounds etc would be really appreciated! > > Thanks a lot in advance, > > Pieter > > "DraguVaso" <pietercou***@hotmail.com> schrieb: .... which is true. It's not the list object which is raising the events. > I have a Generic List, for instance: Public MyPersonnesDeContact As New > System.Collections.Generic.List(Of clsPersonne) > > My clsPersonne raises some events, and I want to be able to handle these > events. The problem is: when using the WithEvents (Public WithEvents > MyPersonnesDeContact As New System.Collections.Generic.List(Of > clsPersonne)) I get an error, saying "'WithEvents' variable does not raise > any events.". The objects stored in/referenced by the list are raising events. Thus you'll have to connect event handlers to the items instea of connecting them to the list. You can use the 'AddHandler' statement in order to add a handler to an item's event. If the events are implemented properly, the 'sender' parameter of the event handler contains a reference to the object which raised the event -- which is especially useful when connecting the same event handler to the events of more than one object. -- M S Herfried K. Wagner M V P <URL:http://dotnet.mvps.org/> V B <URL:http://classicvb.org/petition/> Ok thanks guys! I guess that will be the only solution :) I'll jsut have to
take care to add the handler's every time I add an object, but that will have to be possible, hehe :) thanks a lot, Pieter Show quote "Herfried K. Wagner [MVP]" <hirf-spam-me-here@gmx.at> wrote in message news:e0xmpe%23zFHA.2216@TK2MSFTNGP10.phx.gbl... > "DraguVaso" <pietercou***@hotmail.com> schrieb: >> I have a Generic List, for instance: Public MyPersonnesDeContact As New >> System.Collections.Generic.List(Of clsPersonne) >> >> My clsPersonne raises some events, and I want to be able to handle these >> events. The problem is: when using the WithEvents (Public WithEvents >> MyPersonnesDeContact As New System.Collections.Generic.List(Of >> clsPersonne)) I get an error, saying "'WithEvents' variable does not >> raise any events.". > > ... which is true. It's not the list object which is raising the events. > The objects stored in/referenced by the list are raising events. Thus > you'll have to connect event handlers to the items instea of connecting > them to the list. You can use the 'AddHandler' statement in order to add > a handler to an item's event. If the events are implemented properly, the > 'sender' parameter of the event handler contains a reference to the object > which raised the event -- which is especially useful when connecting the > same event handler to the events of more than one object. > > -- > M S Herfried K. Wagner > M V P <URL:http://dotnet.mvps.org/> > V B <URL:http://classicvb.org/petition/> Pieter,
As Herfreid stated, your clsPersonne raises events List(Of T) does not. It sounds like you want List(Of T) to raise events based on the objects it contains. What I normally do is derive a class from the base collection (List(Of T) in your case), then override the "add" and "remove" of the collection to use AddHandler & RemoveHandler on each object being added or removed from my collection, so that the collection can raise the event that the individual items raise... Something like (.NET 1.1 sample): Public Class Person Public Event NameChanged As EventHandler Private m_name As String Public Property Name() As String Get Return m_name End Get Set(ByVal value As String) m_name = value OnNameChanged(EventArgs.Empty) End Set End Property Protected Overridable Sub OnNameChanged(ByVal e As EventArgs) RaiseEvent NameChanged(Me, e) End Sub Public Overrides Function ToString() As String Return "Person(" & m_name & ")" End Function End Class Public Class PersonCollection 'Inherits CollectionBase Inherits ArrayList Public Event NameChanged As EventHandler Public Overrides Function Add(ByVal value As Object) As Integer Dim person As person = DirectCast(value, person) AddHandler person.NameChanged, AddressOf Person_NameChanged Return MyBase.Add(value) End Function Public Overrides Sub Remove(ByVal value As Object) Dim person As person = DirectCast(value, person) RemoveHandler person.NameChanged, AddressOf Person_NameChanged MyBase.Remove(value) End Sub Private Sub Person_NameChanged(ByVal sender As Object, ByVal e As EventArgs) ' TODO: Consider defining a new EventArgs class that includes person RaiseEvent NameChanged(sender, e) End Sub End Class Private Shared WithEvents people As New PersonCollection Private Shared Sub people_NameChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles people.NameChanged Debug.WriteLine(sender, "NameChanged") End Sub Public Shared Sub Main() Dim person1 As New Person Dim person2 As New Person Dim person3 As New Person people.Add(person1) people.Add(person2) people.Add(person3) person1.Name = "Person 1" person2.Name = "Person 2" person3.Name = "Person 3" people.Remove(person3) person3.Name = String.Empty End Sub You may also need to override Insert & other methods... NOTE: In practice I would have PersonCollection.NameChanged use an EventArgs derived classt that included the Person object that changed, then the sender parameter to the event would be the PersonCollection itself... Show quote "DraguVaso" <pietercou***@hotmail.com> wrote in message news:e5MjPA%23zFHA.2924@TK2MSFTNGP15.phx.gbl... | Hi, | | I have a Generic List, for instance: Public MyPersonnesDeContact As New | System.Collections.Generic.List(Of clsPersonne) | | My clsPersonne raises some events, and I want to be able to handle these | events. The problem is: when using the WithEvents (Public WithEvents | MyPersonnesDeContact As New System.Collections.Generic.List(Of clsPersonne)) | I get an error, saying "'WithEvents' variable does not raise any events.". | | Does anybody know how I could be able to handle events that happens in the | intances of the class in my Generic.List? | | Any help, hints, workarounds etc would be really appreciated! | | Thanks a lot in advance, | | Pieter | | Thanks! That's a great idea! :-)
Show quote "Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_***@tsbradley.net> wrote in message news:eCfBHxC0FHA.916@TK2MSFTNGP10.phx.gbl... > Pieter, > As Herfreid stated, your clsPersonne raises events List(Of T) does not. > > It sounds like you want List(Of T) to raise events based on the objects it > contains. What I normally do is derive a class from the base collection > (List(Of T) in your case), then override the "add" and "remove" of the > collection to use AddHandler & RemoveHandler on each object being added or > removed from my collection, so that the collection can raise the event > that > the individual items raise... > > Something like (.NET 1.1 sample): > > Public Class Person > > Public Event NameChanged As EventHandler > > Private m_name As String > > Public Property Name() As String > Get > Return m_name > End Get > Set(ByVal value As String) > m_name = value > OnNameChanged(EventArgs.Empty) > End Set > End Property > > Protected Overridable Sub OnNameChanged(ByVal e As EventArgs) > RaiseEvent NameChanged(Me, e) > End Sub > > Public Overrides Function ToString() As String > Return "Person(" & m_name & ")" > End Function > > End Class > > Public Class PersonCollection > 'Inherits CollectionBase > Inherits ArrayList > > Public Event NameChanged As EventHandler > > Public Overrides Function Add(ByVal value As Object) As Integer > Dim person As person = DirectCast(value, person) > AddHandler person.NameChanged, AddressOf Person_NameChanged > Return MyBase.Add(value) > End Function > > Public Overrides Sub Remove(ByVal value As Object) > Dim person As person = DirectCast(value, person) > RemoveHandler person.NameChanged, AddressOf Person_NameChanged > MyBase.Remove(value) > End Sub > > Private Sub Person_NameChanged(ByVal sender As Object, ByVal e As > EventArgs) > ' TODO: Consider defining a new EventArgs class that includes > person > RaiseEvent NameChanged(sender, e) > End Sub > > End Class > > Private Shared WithEvents people As New PersonCollection > > Private Shared Sub people_NameChanged(ByVal sender As Object, ByVal e > As > System.EventArgs) Handles people.NameChanged > Debug.WriteLine(sender, "NameChanged") > End Sub > > Public Shared Sub Main() > > Dim person1 As New Person > Dim person2 As New Person > Dim person3 As New Person > > people.Add(person1) > people.Add(person2) > people.Add(person3) > > person1.Name = "Person 1" > person2.Name = "Person 2" > person3.Name = "Person 3" > > people.Remove(person3) > > person3.Name = String.Empty > > End Sub > > You may also need to override Insert & other methods... > > NOTE: In practice I would have PersonCollection.NameChanged use an > EventArgs > derived classt that included the Person object that changed, then the > sender > parameter to the event would be the PersonCollection itself... > > -- > Hope this helps > Jay [MVP - Outlook] > T.S. Bradley - http://www.tsbradley.net > > > "DraguVaso" <pietercou***@hotmail.com> wrote in message > news:e5MjPA%23zFHA.2924@TK2MSFTNGP15.phx.gbl... > | Hi, > | > | I have a Generic List, for instance: Public MyPersonnesDeContact As New > | System.Collections.Generic.List(Of clsPersonne) > | > | My clsPersonne raises some events, and I want to be able to handle these > | events. The problem is: when using the WithEvents (Public WithEvents > | MyPersonnesDeContact As New System.Collections.Generic.List(Of > clsPersonne)) > | I get an error, saying "'WithEvents' variable does not raise any > events.". > | > | Does anybody know how I could be able to handle events that happens in > the > | intances of the class in my Generic.List? > | > | Any help, hints, workarounds etc would be really appreciated! > | > | Thanks a lot in advance, > | > | Pieter > | > | > > Pieter,
Here's a .NET 2.0 sample (VS 2005): It uses System.Collections.ObjectModel.Collection(Of T) for the base of the collection. Collection(Of T) is the replacement for CollectionBase, just as List(Of T) is the replacement for ArrayList. ---x--- cut here ---x--- ' ' Copyright © 2005, Jay B. Harlow, All Rights Reserved. ' Option Strict On Option Explicit On Public Class Person Public Event NameChanged As EventHandler Private ReadOnly m_id As Integer Private m_name As String Public Sub New(ByVal id As Integer) m_id = id End Sub Public ReadOnly Property Id() As Integer Get Return m_id End Get End Property Public Property Name() As String Get Return m_name End Get Set(ByVal value As String) m_name = value OnNameChanged(EventArgs.Empty) End Set End Property Protected Sub OnNameChanged(ByVal e As EventArgs) RaiseEvent NameChanged(Me, e) End Sub Public Overrides Function ToString() As String Return "Person(" & m_id & ", " & m_name & ")" End Function End Class ---x--- cut here ---x--- ' ' Copyright © 2005, Jay B. Harlow, All Rights Reserved. ' Option Strict On Option Explicit On Public Class PersonCollection Inherits System.Collections.ObjectModel.Collection(Of Person) Public Event PersonNameChanged As EventHandler(Of PersonNameChangedEventArgs) Protected Overrides Sub ClearItems() For Each item As Person In Me RemoveHandler item.NameChanged, AddressOf OnNameChanged Next MyBase.ClearItems() End Sub Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item As Person) AddHandler item.NameChanged, AddressOf OnNameChanged MyBase.InsertItem(index, item) End Sub Protected Overrides Sub RemoveItem(ByVal index As Integer) Dim item As Person = Me(index) RemoveHandler item.NameChanged, AddressOf OnNameChanged MyBase.RemoveItem(index) End Sub Protected Overrides Sub SetItem(ByVal index As Integer, ByVal item As Person) Dim itemOriginal As Person = Me(index) RemoveHandler itemOriginal.NameChanged, AddressOf OnNameChanged AddHandler item.NameChanged, AddressOf OnNameChanged MyBase.SetItem(index, item) End Sub Private Sub OnNameChanged(ByVal sender As Object, ByVal e As EventArgs) Dim args As New PersonNameChangedEventArgs(DirectCast(sender, Person)) OnPersonNameChanged(args) End Sub Protected Overridable Sub OnPersonNameChanged(ByVal e As PersonNameChangedEventArgs) RaiseEvent PersonNameChanged(Me, e) End Sub End Class ---x--- cut here ---x--- ' ' Copyright © 2005, Jay B. Harlow, All Rights Reserved. ' Option Strict On Option Explicit On Public Class PersonNameChangedEventArgs Inherits EventArgs Private ReadOnly m_person As Person Public Sub New(ByVal person As Person) m_person = person End Sub Public ReadOnly Property Person() As Person Get Return m_person End Get End Property End Class ---x--- cut here ---x--- ' ' Copyright © 2005, Jay B. Harlow, All Rights Reserved. ' Option Strict On Option Explicit On Public Module MainModule Private WithEvents people As New PersonCollection Public Sub Main() Dim person1 As New Person(1) Dim person2 As New Person(2) Dim person3 As New Person(3) people.Add(person1) people.Add(person2) people.Add(person3) person1.Name = "Person 1" person2.Name = "Person 2" person3.Name = "Person 3" people.Remove(person3) person3.Name = String.Empty people(0) = person3 person1.Name = String.Empty person3.Name = "Jay" people.Clear() person1.Name = String.Empty person2.Name = String.Empty person3.Name = String.Empty End Sub Private Sub People_PersonNameChanged(ByVal sender As Object, ByVal e As PersonNameChangedEventArgs) Handles people.PersonNameChanged Debug.WriteLine(e.Person, "Person Name Changed") End Sub End Module ---x--- cut here ---x--- Show quote "DraguVaso" <pietercou***@hotmail.com> wrote in message <<snip>>news:OUwX$hJ0FHA.1028@TK2MSFTNGP12.phx.gbl... | Thanks! That's a great idea! :-) | | "Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_***@tsbradley.net> wrote in | message news:eCfBHxC0FHA.916@TK2MSFTNGP10.phx.gbl... | > Pieter, | > As Herfreid stated, your clsPersonne raises events List(Of T) does not. | > | > It sounds like you want List(Of T) to raise events based on the objects it | > contains. What I normally do is derive a class from the base collection | > (List(Of T) in your case), then override the "add" and "remove" of the | > collection to use AddHandler & RemoveHandler on each object being added or | > removed from my collection, so that the collection can raise the event | > that | > the individual items raise... | > Thanks, that's a great sample!
Just one thing I've been googling around for, but didn't find (and I guess it's not possible): In my case I use the my clsBaseClass instead of Person, because I want to make one type of List which I can use with all my different types of classes (which inherits all of clsBaseClass). But with your solution I can make a List, and add first a clsAdress, and then a clsPerson, which shouldn't be possible with a genric List. But I guess it just isn't possible... But thanks a lot anyways for the great help and sample that helped me a lot! Pieter Show quote "Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_***@tsbradley.net> wrote in message news:eS2q4BO0FHA.3256@TK2MSFTNGP09.phx.gbl... > Pieter, > Here's a .NET 2.0 sample (VS 2005): > > It uses System.Collections.ObjectModel.Collection(Of T) for the base of > the > collection. Collection(Of T) is the replacement for CollectionBase, just > as > List(Of T) is the replacement for ArrayList. > > ---x--- cut here ---x--- > ' > ' Copyright © 2005, Jay B. Harlow, All Rights Reserved. > ' > Option Strict On > Option Explicit On > > Public Class Person > > Public Event NameChanged As EventHandler > > Private ReadOnly m_id As Integer > Private m_name As String > > Public Sub New(ByVal id As Integer) > m_id = id > End Sub > > Public ReadOnly Property Id() As Integer > Get > Return m_id > End Get > End Property > > Public Property Name() As String > Get > Return m_name > End Get > Set(ByVal value As String) > m_name = value > OnNameChanged(EventArgs.Empty) > End Set > End Property > > Protected Sub OnNameChanged(ByVal e As EventArgs) > RaiseEvent NameChanged(Me, e) > End Sub > > Public Overrides Function ToString() As String > Return "Person(" & m_id & ", " & m_name & ")" > End Function > > End Class > ---x--- cut here ---x--- > ' > ' Copyright © 2005, Jay B. Harlow, All Rights Reserved. > ' > Option Strict On > Option Explicit On > > Public Class PersonCollection > Inherits System.Collections.ObjectModel.Collection(Of Person) > > Public Event PersonNameChanged As EventHandler(Of > PersonNameChangedEventArgs) > > Protected Overrides Sub ClearItems() > For Each item As Person In Me > RemoveHandler item.NameChanged, AddressOf OnNameChanged > Next > MyBase.ClearItems() > End Sub > > Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item > As > Person) > AddHandler item.NameChanged, AddressOf OnNameChanged > MyBase.InsertItem(index, item) > End Sub > > Protected Overrides Sub RemoveItem(ByVal index As Integer) > Dim item As Person = Me(index) > RemoveHandler item.NameChanged, AddressOf OnNameChanged > MyBase.RemoveItem(index) > End Sub > > Protected Overrides Sub SetItem(ByVal index As Integer, ByVal item As > Person) > Dim itemOriginal As Person = Me(index) > RemoveHandler itemOriginal.NameChanged, AddressOf OnNameChanged > AddHandler item.NameChanged, AddressOf OnNameChanged > MyBase.SetItem(index, item) > End Sub > > Private Sub OnNameChanged(ByVal sender As Object, ByVal e As EventArgs) > Dim args As New PersonNameChangedEventArgs(DirectCast(sender, > Person)) > OnPersonNameChanged(args) > End Sub > > Protected Overridable Sub OnPersonNameChanged(ByVal e As > PersonNameChangedEventArgs) > RaiseEvent PersonNameChanged(Me, e) > End Sub > > End Class > ---x--- cut here ---x--- > ' > ' Copyright © 2005, Jay B. Harlow, All Rights Reserved. > ' > Option Strict On > Option Explicit On > > Public Class PersonNameChangedEventArgs > Inherits EventArgs > > Private ReadOnly m_person As Person > > Public Sub New(ByVal person As Person) > m_person = person > End Sub > > Public ReadOnly Property Person() As Person > Get > Return m_person > End Get > End Property > > End Class > ---x--- cut here ---x--- > ' > ' Copyright © 2005, Jay B. Harlow, All Rights Reserved. > ' > Option Strict On > Option Explicit On > > Public Module MainModule > > Private WithEvents people As New PersonCollection > > Public Sub Main() > Dim person1 As New Person(1) > Dim person2 As New Person(2) > Dim person3 As New Person(3) > people.Add(person1) > people.Add(person2) > people.Add(person3) > > person1.Name = "Person 1" > person2.Name = "Person 2" > person3.Name = "Person 3" > > people.Remove(person3) > person3.Name = String.Empty > > people(0) = person3 > person1.Name = String.Empty > person3.Name = "Jay" > > people.Clear() > person1.Name = String.Empty > person2.Name = String.Empty > person3.Name = String.Empty > > End Sub > > Private Sub People_PersonNameChanged(ByVal sender As Object, ByVal e As > PersonNameChangedEventArgs) Handles people.PersonNameChanged > Debug.WriteLine(e.Person, "Person Name Changed") > End Sub > > End Module > ---x--- cut here ---x--- > > -- > Hope this helps > Jay [MVP - Outlook] > T.S. Bradley - http://www.tsbradley.net > > > "DraguVaso" <pietercou***@hotmail.com> wrote in message > news:OUwX$hJ0FHA.1028@TK2MSFTNGP12.phx.gbl... > | Thanks! That's a great idea! :-) > | > | "Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_***@tsbradley.net> wrote in > | message news:eCfBHxC0FHA.916@TK2MSFTNGP10.phx.gbl... > | > Pieter, > | > As Herfreid stated, your clsPersonne raises events List(Of T) does > not. > | > > | > It sounds like you want List(Of T) to raise events based on the > objects > it > | > contains. What I normally do is derive a class from the base > collection > | > (List(Of T) in your case), then override the "add" and "remove" of the > | > collection to use AddHandler & RemoveHandler on each object being > added > or > | > removed from my collection, so that the collection can raise the event > | > that > | > the individual items raise... > | > > <<snip>> > > As a matter of fact: I'm now getting in trouble, because I can't use my List
anymore as a DataSource for a DataGridView or stuff like that! My DataGridView shows only the propertys of my clsBaseclass, and not those of my clsPerson or clsAdress or ... Any idea how to get around this? Thanks a lot in advance, Pieter Show quote "DraguVaso" <pietercou***@hotmail.com> wrote in message news:uygK62u0FHA.2884@TK2MSFTNGP09.phx.gbl... > Thanks, that's a great sample! > > Just one thing I've been googling around for, but didn't find (and I guess > it's not possible): In my case I use the my clsBaseClass instead of > Person, because I want to make one type of List which I can use with all > my different types of classes (which inherits all of clsBaseClass). But > with your solution I can make a List, and add first a clsAdress, and then > a clsPerson, which shouldn't be possible with a genric List. But I guess > it just isn't possible... > > But thanks a lot anyways for the great help and sample that helped me a > lot! > > Pieter > > > "Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_***@tsbradley.net> wrote in > message news:eS2q4BO0FHA.3256@TK2MSFTNGP09.phx.gbl... >> Pieter, >> Here's a .NET 2.0 sample (VS 2005): >> >> It uses System.Collections.ObjectModel.Collection(Of T) for the base of >> the >> collection. Collection(Of T) is the replacement for CollectionBase, just >> as >> List(Of T) is the replacement for ArrayList. >> >> ---x--- cut here ---x--- >> ' >> ' Copyright © 2005, Jay B. Harlow, All Rights Reserved. >> ' >> Option Strict On >> Option Explicit On >> >> Public Class Person >> >> Public Event NameChanged As EventHandler >> >> Private ReadOnly m_id As Integer >> Private m_name As String >> >> Public Sub New(ByVal id As Integer) >> m_id = id >> End Sub >> >> Public ReadOnly Property Id() As Integer >> Get >> Return m_id >> End Get >> End Property >> >> Public Property Name() As String >> Get >> Return m_name >> End Get >> Set(ByVal value As String) >> m_name = value >> OnNameChanged(EventArgs.Empty) >> End Set >> End Property >> >> Protected Sub OnNameChanged(ByVal e As EventArgs) >> RaiseEvent NameChanged(Me, e) >> End Sub >> >> Public Overrides Function ToString() As String >> Return "Person(" & m_id & ", " & m_name & ")" >> End Function >> >> End Class >> ---x--- cut here ---x--- >> ' >> ' Copyright © 2005, Jay B. Harlow, All Rights Reserved. >> ' >> Option Strict On >> Option Explicit On >> >> Public Class PersonCollection >> Inherits System.Collections.ObjectModel.Collection(Of Person) >> >> Public Event PersonNameChanged As EventHandler(Of >> PersonNameChangedEventArgs) >> >> Protected Overrides Sub ClearItems() >> For Each item As Person In Me >> RemoveHandler item.NameChanged, AddressOf OnNameChanged >> Next >> MyBase.ClearItems() >> End Sub >> >> Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item >> As >> Person) >> AddHandler item.NameChanged, AddressOf OnNameChanged >> MyBase.InsertItem(index, item) >> End Sub >> >> Protected Overrides Sub RemoveItem(ByVal index As Integer) >> Dim item As Person = Me(index) >> RemoveHandler item.NameChanged, AddressOf OnNameChanged >> MyBase.RemoveItem(index) >> End Sub >> >> Protected Overrides Sub SetItem(ByVal index As Integer, ByVal item As >> Person) >> Dim itemOriginal As Person = Me(index) >> RemoveHandler itemOriginal.NameChanged, AddressOf OnNameChanged >> AddHandler item.NameChanged, AddressOf OnNameChanged >> MyBase.SetItem(index, item) >> End Sub >> >> Private Sub OnNameChanged(ByVal sender As Object, ByVal e As >> EventArgs) >> Dim args As New PersonNameChangedEventArgs(DirectCast(sender, >> Person)) >> OnPersonNameChanged(args) >> End Sub >> >> Protected Overridable Sub OnPersonNameChanged(ByVal e As >> PersonNameChangedEventArgs) >> RaiseEvent PersonNameChanged(Me, e) >> End Sub >> >> End Class >> ---x--- cut here ---x--- >> ' >> ' Copyright © 2005, Jay B. Harlow, All Rights Reserved. >> ' >> Option Strict On >> Option Explicit On >> >> Public Class PersonNameChangedEventArgs >> Inherits EventArgs >> >> Private ReadOnly m_person As Person >> >> Public Sub New(ByVal person As Person) >> m_person = person >> End Sub >> >> Public ReadOnly Property Person() As Person >> Get >> Return m_person >> End Get >> End Property >> >> End Class >> ---x--- cut here ---x--- >> ' >> ' Copyright © 2005, Jay B. Harlow, All Rights Reserved. >> ' >> Option Strict On >> Option Explicit On >> >> Public Module MainModule >> >> Private WithEvents people As New PersonCollection >> >> Public Sub Main() >> Dim person1 As New Person(1) >> Dim person2 As New Person(2) >> Dim person3 As New Person(3) >> people.Add(person1) >> people.Add(person2) >> people.Add(person3) >> >> person1.Name = "Person 1" >> person2.Name = "Person 2" >> person3.Name = "Person 3" >> >> people.Remove(person3) >> person3.Name = String.Empty >> >> people(0) = person3 >> person1.Name = String.Empty >> person3.Name = "Jay" >> >> people.Clear() >> person1.Name = String.Empty >> person2.Name = String.Empty >> person3.Name = String.Empty >> >> End Sub >> >> Private Sub People_PersonNameChanged(ByVal sender As Object, ByVal e >> As >> PersonNameChangedEventArgs) Handles people.PersonNameChanged >> Debug.WriteLine(e.Person, "Person Name Changed") >> End Sub >> >> End Module >> ---x--- cut here ---x--- >> >> -- >> Hope this helps >> Jay [MVP - Outlook] >> T.S. Bradley - http://www.tsbradley.net >> >> >> "DraguVaso" <pietercou***@hotmail.com> wrote in message >> news:OUwX$hJ0FHA.1028@TK2MSFTNGP12.phx.gbl... >> | Thanks! That's a great idea! :-) >> | >> | "Jay B. Harlow [MVP - Outlook]" <Jay_Harlow_***@tsbradley.net> wrote in >> | message news:eCfBHxC0FHA.916@TK2MSFTNGP10.phx.gbl... >> | > Pieter, >> | > As Herfreid stated, your clsPersonne raises events List(Of T) does >> not. >> | > >> | > It sounds like you want List(Of T) to raise events based on the >> objects >> it >> | > contains. What I normally do is derive a class from the base >> collection >> | > (List(Of T) in your case), then override the "add" and "remove" of >> the >> | > collection to use AddHandler & RemoveHandler on each object being >> added >> or >> | > removed from my collection, so that the collection can raise the >> event >> | > that >> | > the individual items raise... >> | > >> <<snip>> >> >> > > Ok, I finally have what I want! It took me a lot of time, research and help
of people on thesen ewsgroups, but now I have it: a Generic.List(Of ) that has: - AND ALL the possiblities and features of a normal Generic.List(Of ) - AND has customized possiblites to a give type of base-class, and the possiblitie to trigger events of that base-class. All classes used with this 'new' list must offcourse inherit of this base-class... The sample code: Public Class clsBaseList(Of T As clsBaseClass) Inherits System.Collections.Generic.List(Of T) 'property's, methods etc... '... #Region "List Methods" Protected Overridable Sub OnPropertyChanged(ByVal sender As Object, ByVal e As HasChangesEventArgs) 'always... RaiseEvent HasChangesChanged(Me, e) End Sub Public Shadows Sub Add(ByVal item As T) AddHandler item.HasChangesChanged, AddressOf Me.OnPropertyChanged MyBase.Add(item) End Sub Public Shadows Sub Insert(ByVal index As Integer, ByVal item As T) AddHandler item.HasChangesChanged, AddressOf Me.OnPropertyChanged MyBase.Insert(index, item) End Sub Public Shadows Sub Clear() For Each item As clsBaseClass In Me RemoveHandler item.HasChangesChanged, AddressOf OnPropertyChanged Next MyBase.Clear() End Sub Public Shadows Function Remove(ByVal item As T) As Boolean RemoveHandler item.HasChangesChanged, AddressOf OnPropertyChanged Return MyBase.Remove(item) End Function Public Shadows Sub RemoveAt(ByVal index As Integer) RemoveHandler MyBase.Item(index).HasChangesChanged, AddressOf OnPropertyChanged MyBase.RemoveAt(index) End Sub 'very import, otherwise it will return objects of clsBaseClass, and not object of T... Default Public Shadows Property Item(ByVal index As Integer) As T Get Return MyBase.Item(index) End Get Set(ByVal value As T) AddHandler value.HasChangesChanged, AddressOf Me.OnPropertyChanged MyBase.Item(index) = value End Set End Property #End Region End Class Show quote "DraguVaso" <pietercou***@hotmail.com> wrote in message news:e5MjPA%23zFHA.2924@TK2MSFTNGP15.phx.gbl... > Hi, > > I have a Generic List, for instance: Public MyPersonnesDeContact As New > System.Collections.Generic.List(Of clsPersonne) > > My clsPersonne raises some events, and I want to be able to handle these > events. The problem is: when using the WithEvents (Public WithEvents > MyPersonnesDeContact As New System.Collections.Generic.List(Of > clsPersonne)) I get an error, saying "'WithEvents' variable does not raise > any events.". > > Does anybody know how I could be able to handle events that happens in the > intances of the class in my Generic.List? > > Any help, hints, workarounds etc would be really appreciated! > > Thanks a lot in advance, > > Pieter > > DraguVaso,
Looks good. However! I would strongly recommend using a collection such as System.Collections.ObjectModel.Collection(Of T) as a starting point instead of List(Of T). As Collection(Of T) is designed to be inherited from, where as List(Of T) is not. http://msdn2.microsoft.com/en-us/library/ms132397(en-US,VS.80).aspx Using Shadows to design a derived class can be very problematic at best, as Shadows is anti-Polymorphic, you need to use Overrides for Polymorphic behaving. Consider the following: Dim list As List(Of Person) = New clsBaseList(Of Person) list.Add(New Person(...)) clsBaseList.Add will not be called as you Shadowed List(Of T).Add. Seeing as you have a List(Of T) variable, List(Of T).Add will be called. If you have a clsBaseList(Of T) variable, then clsBaseList(Of T).Add will be called. If you Override List(Of T).Add then it would be polymorphic & clsBaseList(Of T).Add will be called above. Show quote "DraguVaso" <pietercou***@hotmail.com> wrote in message news:%23w0OKRw0FHA.3180@TK2MSFTNGP14.phx.gbl... | Ok, I finally have what I want! It took me a lot of time, research and help | of people on thesen ewsgroups, but now I have it: a Generic.List(Of ) that | has: | - AND ALL the possiblities and features of a normal Generic.List(Of ) | - AND has customized possiblites to a give type of base-class, and the | possiblitie to trigger events of that base-class. All classes used with this | 'new' list must offcourse inherit of this base-class... | | The sample code: | | Public Class clsBaseList(Of T As clsBaseClass) | Inherits System.Collections.Generic.List(Of T) | | 'property's, methods etc... | '... | | #Region "List Methods" | Protected Overridable Sub OnPropertyChanged(ByVal sender As Object, | ByVal e As HasChangesEventArgs) | 'always... | RaiseEvent HasChangesChanged(Me, e) | End Sub | | Public Shadows Sub Add(ByVal item As T) | AddHandler item.HasChangesChanged, AddressOf Me.OnPropertyChanged | MyBase.Add(item) | End Sub | | Public Shadows Sub Insert(ByVal index As Integer, ByVal item As T) | AddHandler item.HasChangesChanged, AddressOf Me.OnPropertyChanged | MyBase.Insert(index, item) | End Sub | | Public Shadows Sub Clear() | For Each item As clsBaseClass In Me | RemoveHandler item.HasChangesChanged, AddressOf | OnPropertyChanged | Next | MyBase.Clear() | End Sub | | Public Shadows Function Remove(ByVal item As T) As Boolean | RemoveHandler item.HasChangesChanged, AddressOf OnPropertyChanged | Return MyBase.Remove(item) | End Function | | Public Shadows Sub RemoveAt(ByVal index As Integer) | RemoveHandler MyBase.Item(index).HasChangesChanged, AddressOf | OnPropertyChanged | MyBase.RemoveAt(index) | End Sub | | 'very import, otherwise it will return objects of clsBaseClass, and not | object of T... | Default Public Shadows Property Item(ByVal index As Integer) As T | Get | Return MyBase.Item(index) | End Get | Set(ByVal value As T) | AddHandler value.HasChangesChanged, AddressOf | Me.OnPropertyChanged | MyBase.Item(index) = value | End Set | End Property | | #End Region | | End Class | | | "DraguVaso" <pietercou***@hotmail.com> wrote in message | news:e5MjPA%23zFHA.2924@TK2MSFTNGP15.phx.gbl... | > Hi, | > | > I have a Generic List, for instance: Public MyPersonnesDeContact As New | > System.Collections.Generic.List(Of clsPersonne) | > | > My clsPersonne raises some events, and I want to be able to handle these | > events. The problem is: when using the WithEvents (Public WithEvents | > MyPersonnesDeContact As New System.Collections.Generic.List(Of | > clsPersonne)) I get an error, saying "'WithEvents' variable does not raise | > any events.". | > | > Does anybody know how I could be able to handle events that happens in the | > intances of the class in my Generic.List? | > | > Any help, hints, workarounds etc would be really appreciated! | > | > Thanks a lot in advance, | > | > Pieter | > | > | | |
|||||||||||||||||||||||