ObservableList and CollectionChanged event

2 posts, 1 answers
  1. Sergej Mertens
    Sergej Mertens avatar
    34 posts
    Member since:
    May 2009

    Posted 26 May 2009 Link to this post


    I have two objects "Invoice" and "Details". The Invoice class holds a field of ObservableCollection<Details> and therefore has a Property called "InvoiceDetails". In Invoice I create the ObservableCollection-Object and add an eventhandler to the CollectionChanged event.

    I now load a previously saved instance from Invoice and add a new Detail to the Collection. All went fine, but the event does not fire.
    I tried the same with a BindingList and it's the same behaviour: no event fires.

    Example (in VB):

    public class Invoice
       Dim _details as ObservableCollection(Of Details) = new ObservableCollection(Of Details)()

       public sub New()
          AddHandler _details.CollectionChanged, AddressOf details_CollectionChanged
       end sub
       public property InvoiceDetails() as ObservableCollection(Of Details)
             return _details
          end get
       end property

       private sub details_CollectionChanged(sender as Object, e as EventArgs)
          MessageBox.Show("Detail added")
       end sub

    end class

    and in a form I call:
    dim result as Invoice = (From i in scope.Extent(of Invoice)() Where i.Id = 1 Select i).First()
    result.Add(new Detail())

    My tasks to solve are:
    - I have an object and need to know every change of all sub- und listed objects in this instance. They all implement INotifyPropertyChanged for tracking the changed object and property
    - I have a collection to which an instance is added, removed or changed. I now have to recalculate totals and subtotals in the "master" object
    - Tracking changes of Collections while this collection is databound to e.g. an UltraWinGrid

    Daniel Schilling

    Edit: Typo

  2. Answer
    PetarP avatar
    754 posts

    Posted 29 May 2009 Link to this post

    Hi Daniel Schilling,
    the event is not firing because you have not subscribed on the right place. If you let your class implement the
    IInstanceCallbacks interface than you will have access to the lifecycle events of the persistent objects. This interface contains 3 methods that need to be implemented:
    PostLoad() - fires when the first persistent field of a class is accessed. You can subscribe your collection to the event handler here
    PreRemove(Iobjectscope scope) - this emthod is fired when an object is being removed from the scope
    PreStore() - this method is fired when an object is being saved to the database.
    To give you an example. If we have 2 classes, Details and Invoices and we let the Invoice implement the IInstanceCallbacks than we will have something similar to that:
    <Telerik.OpenAccess.Persistent(IdentityField:="invoiceId_Renamed")> _ 
        Public Class Invoice 
            Implements IInstanceCallbacks 
            Private invoiceId_Renamed As Integer 
            <Telerik.OpenAccess.FieldAlias("invoiceId_Renamed")> _ 
            Public Property InvoiceId() As Integer 
                    Return invoiceId_Renamed 
                End Get 
                Set(ByVal value As Integer
                    invoiceId_Renamed = value 
                End Set 
            End Property 
            Private invoiceDescription_Renamed As String 
            <Telerik.OpenAccess.FieldAlias("invoiceDescription_Renamed")> _ 
            Public Property InvoiceDescription() As String 
                    Return invoiceDescription_Renamed 
                End Get 
                Set(ByVal value As String
                    invoiceDescription_Renamed = value 
                End Set 
            End Property 
            Private details_Renamed As ObservableCollection(Of Detail) 
            Public Property Details() As ObservableCollection(Of Detail) 
                    Return details_Renamed 
                End Get 
                Set(ByVal value As ObservableCollection(Of Detail)) 
                    details_Renamed = value 
                End Set 
            End Property 
            Public Sub PostLoad() Implements Telerik.OpenAccess.IInstanceCallbacks.PostLoad 
                AddHandler details_Renamed.CollectionChanged, AddressOf details_CollectionChanged 
            End Sub 
            Public Sub PreRemove(ByVal objectScope As Telerik.OpenAccess.IObjectScope) Implements Telerik.OpenAccess.IInstanceCallbacks.PreRemove 
            End Sub 
            Public Sub PreStore() Implements Telerik.OpenAccess.IInstanceCallbacks.PreStore 
            End Sub 
            Private Sub details_CollectionChanged(ByVal sender As ObjectByVal e As System.Collections.Specialized.NotifyCollectionChangedEventArgs) 
            End Sub 
        End Class 

    I believe that you will find this article useful.

    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  3. DevCraft banner
Back to Top