Click here to Skip to main content
Click here to Skip to main content

Generic List of Mutable Objects with Events

By , 7 Aug 2007
Rate this:
Please Sign up or sign in to vote.

Introduction

Most applications directly or indirectly deal with databases and collections of objects. These collections are bound to some UI shown to the user, updated, saved... Well, you know the drill. Here, I would like to share the approach that works best for me.

ListWithEvents<T>

First of all, I needed to be able to know when an item was added, removed or modified in the collection. None of the provided collections could handle that (or have I just missed it?). So, I made my own: ListWithEvents<T>. All I did was overload the existing methods of the List<T> class and introduce the required events.

Screenshot - listwithevents.jpg

There is nothing really fancy about this. The only thing I have added to the collection is an ability to perform batch actions that raise only a single event. To switch to batch update, call SuppressEvents(). Once events are suppressed, the collection tracks events that would have been raised otherwise. As soon as the ResumeEvents() method is called, the collection fires up those events, one of each kind.

MutableObject

To start with, I wanted to have a base object, so I made one: MutableObject. The class has only a few properties, events and methods. The object is also capable of serialising and deserialising itself as XML.

Screenshot - mutableobject.jpg

There is nothing really fancy about those except the implementation of Clone(). I needed a real deep-clone functionality and, considering it is a base class, the last thing I wanted was to provide implementation in every descendant of my MutableObject.

So, after some Googling, I came across an article by Renfield on it. I took the guy's idea and, having fixed a few problems and enhanced it along the way, I made my MutableObject cloning all of its writable properties and fields. One thing that should be noted here, however, is that reference-type properties will only be deeply cloned if they implement the IClonable interface.

ListOfMutableObjects<T>

Now creating a ListOfMutableObjects<T> collection seems like a very reasonable step. You need to overload a number of methods handling item addition, removal and modification wiring to/unwiring from the item's Modified event.

Screenshot - listofmutableobjects.jpg

I mentioned the batch action mode earlier. This is particularly useful when you update a number of properties for some item in the collection. For instance:

class MyObject : MutableObject
{
    private int p1, p2;

    public int P1
    {
        get 
        { 
            return this.p1; 
        }
        set
        {
            if (this.p1 != value)
            {
                this.p1 = value;
                this.OnModified(EventArgs.Empty);
            }
        }
    }

    public int P2
    {
        get 
        { 
            return this.p2; 
        }
        set
        {
            if (this.p2 != value)
            {
                this.p2 = value;
                this.OnModified(EventArgs.Empty);
            }
        }
    }
}

Assuming that there is ListOfMutableObjects<MyObject> mylist and you have wired up the ItemModified and/or CollectionModified events, you will have the following code to modify an item in the collection:

mylist.SuppressEvents();
mylist[0].P1 = 5;
mylist[0].P2 = 10;
mylist.ResumeEvents();

This way, you will have only one event notification instead of two.

Update to Version 1.3.1

Some time ago, I realised a few shortfalls that got fixed in this version. To start with, I have made the list thread-safe and exposed a public SyncRoot property. Next, I refactored the CollectionModified event to be fired by a designated method: OnCollectionModified(). I have also changed the signature of the event to EventHandler<ListModificationEventArgs> and created a ListModificationEventArgs class. Thirdly, I have discarded all of the custom event handlers and replaced them with EventHandler<T> handlers, where T represents appropriate event arguments.

Another minor change includes the marking of all shadowed methods with the "virtual" keyword, providing the class descendants with the opportunity to override the methods rather than shadowing them again.

At one point when I was building a UI with a PropertyGrid control and an instance of ListWithEvents, I noticed that the Collection Editor UI didn't seem to be calling my Add() methods. So, to address the problem I had to provide an explicit implementation of the IList.Add() method. After that, the UI would correctly wire up -- and subsequently fire -- events to new items.

Perhaps the last addition to the library worth mentioning is the ClonableListWithEvents<T> class. You can probably guess from the name that it is a list with events for objects implementing the IClonable interface.

public class ClonableListWithEvents<T> : ListWithEvents<T>, ICloneable
    where T : ICloneable
{
    ...
    public virtual ClonableListWithEvents<T> Clone();
}

History

  • 9 Mar 2007 - Initial submission; version 1.0.0.0
  • 6 Jul 2007 - Updated to version 1.3.1.0
  • 7 Aug 2007 - Updated to version 1.3.1.1

Final Words

Well that's all folks. I hope someone will find it useful.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Igor Velikorossov
Software Developer (Senior)
Australia Australia
No Biography provided

Comments and Discussions

 
GeneralMuch Thanks PinmemberMerrillMarie9-Nov-08 7:23 
GeneralSuppressEvents doe not seem to work Pinmemberantoschka13-Oct-08 2:36 
GeneralRe: SuppressEvents doe not seem to work PinmemberIgor Velikorossov22-Oct-08 20:26 
GeneralBindingList & INotifyPropertyChanged Pinmemberbxb26-Oct-07 4:47 
QuestionCan the CtrlSoft.dll be bundled and redistributed with proprietary software ? Pinmembermali7631-Aug-07 7:26 
AnswerRe: Can the CtrlSoft.dll be bundled and redistributed with proprietary software ? PinmemberIgor Velikorossov2-Sep-07 4:14 
GeneralRe: Can the CtrlSoft.dll be bundled and redistributed with proprietary software ? Pinmemberreflex@codeproject26-May-09 8:59 
GeneralRe: Can the CtrlSoft.dll be bundled and redistributed with proprietary software ? PinmemberIgor Velikorossov27-May-09 2:16 
GeneralObservableCollection Generic Class [modified] Pinmembertarasn9-Aug-07 5:47 
GeneralRe: ObservableCollection Generic Class PinmemberIgor Velikorossov13-Aug-07 15:07 
GeneralCloning PinmemberErnest Bariq17-Mar-07 14:13 
GeneralRe: Cloning PinmemberIgor Velikorossov18-Mar-07 13:08 
QuestionDo you know the System.Collections.ObjectModel namespace ? PinmemberDeclercq Dirk12-Mar-07 2:25 
AnswerRe: Do you know the System.Collections.ObjectModel namespace ? PinmemberSebastien Lorion12-Mar-07 5:45 
GeneralBindingList Pinmemberpurplepangolin9-Mar-07 4:50 
GeneralRe: BindingList PinmemberIgor Velikorossov18-Mar-07 13:10 
Generalcomponent based software modeling PinmemberAndreas Hollmann9-Mar-07 3:00 
GeneralRe: component based software modeling PinmemberIgor Velikorossov9-Mar-07 3:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140415.2 | Last Updated 7 Aug 2007
Article Copyright 2007 by Igor Velikorossov
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid