Home All Groups Group Topic Archive Search About

How to Handle clsMyClass.Event raised in GenericList(Of clsMyClass)

Author
13 Oct 2005 10:22 AM
DraguVaso
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

Author
13 Oct 2005 10:28 AM
Cor Ligthert [MVP]
Pieter,

Are you sure that your class raises "Public" events.

Fist guess

:-)

Cor
Author
13 Oct 2005 10:42 AM
DraguVaso
hehe 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
>
Author
13 Oct 2005 10:43 AM
Atul
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
>
>
Author
13 Oct 2005 10:54 AM
Ken Tucker [MVP]
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
>
>
Author
13 Oct 2005 11:17 AM
Herfried K. Wagner [MVP]
"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/>
Author
13 Oct 2005 11:51 AM
DraguVaso
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/>
Author
13 Oct 2005 7:28 PM
Jay B. Harlow [MVP - Outlook]
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


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
|
|
Author
14 Oct 2005 8:23 AM
DraguVaso
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
> |
> |
>
>
Author
14 Oct 2005 4:57 PM
Jay B. Harlow [MVP - Outlook]
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


Show quote
"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>>
Author
17 Oct 2005 7:38 AM
DraguVaso
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>>
>
>
Author
17 Oct 2005 9:07 AM
DraguVaso
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>>
>>
>>
>
>
Author
17 Oct 2005 10:19 AM
DraguVaso
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
>
>
Author
18 Oct 2005 2:54 AM
Jay B. Harlow [MVP - Outlook]
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.

--
Hope this helps
Jay [MVP - Outlook]
T.S. Bradley - http://www.tsbradley.net


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
| >
| >
|
|

AddThis Social Bookmark Button