TheChaseMan's Frenetic SoapBox

Always looking for better ways to do things...

Custom Collections: Collection<T> and BindingList<T>

As happy as I am with List<T>, lately I've been looking into using Collection<T> from the System.Collections.ObjectModel namespace for my custom business objects. However, BindingList<T> from System.ComponentModel looks very tempting for databinding purposes, plus the nifty AddingNew and ListChanged events it exposes. Despite the ability to do 2-way databinding in WinForm applications using BindingList<T> and some events you can hook, the real focus I have is in ASP.NET databinding. ASP.NET databinding is far more primitive than what you see with WinForms or WPF. WPF (WinFX actually) has ObservableCollection for its rich databinding scheme, which is even more interesting but I digress. The real point of all of this is to have a base class for custom collections for encapsulating things such as sorting algorithms, etc. Certainly you can expose List<T> from your object model, but inheriting from the abstract classes such as Collection<T> or BindingList<T> provides more extensibility. Since BindingList<T> inherits from Collection<T>, maybe it makes more sense to go with BindingList<T>.

I guess my one big question is: what does having the ability to override BindingList<T>.ApplySortCore() get for me? For example, I need to implement a Sort:

public class Person {

    private string _name;

    private int _age;

 

    public Person(string name, int age) {

        _name = name;

        _age = age;

    }

 

    public int Age {

        get { return _age; }

        set { _age = value; }

    }

     

 

    public string Name {

        get { return _name; }

        set { _name = value; }

    }
}

public class PersonCollection : BindingList<Person> {

    protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction) {

        List<Person> items = this.Items as List<Person>;

        //PropertyComparer Source: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnadvnet/html/vbnet01272004.asp

        PropertyComparer<Person> pc = new PropertyComparer<Person>(property, direction);

        items.Sort(pc);

    }

  

    public void SortByName(ListSortDirection direction) {

        PropertyDescriptorCollection propDescriptors = TypeDescriptor.GetProperties(typeof(Person));

        this.ApplySortCore(propDescriptors["Name"], direction);

    }

}

class Program {

    static void Main(string[] args) {

        PersonCollection collection = new PersonCollection();

      

        collection.Add(new Person("Jim", 33));

        collection.Add(new Person("Bob", 20));

        collection.SortByName(ListSortDirection.Ascending);

 

        foreach (Person p in collection) {

            Console.WriteLine("{0} {1}", p.Name, p.Age);

        }

    }
}

I can pretty easily create Sort methods inheriting from Collection<T> doing stuff like this..

public class PersonCollection : Collection<Person> {

    public void SortByName(ListSortDirection direction) {

        List<Person> people = this.Items as List<Person>;

        people.Sort(delegate(Person x, Person y) {

            return Comparer<string>.Default.Compare(x.Name, y.Name) * (direction == ListSortDirection.Descending ? -1 : 1);

        });

    }
}

Any thoughts?
Digg!

posted on Saturday, December 10, 2005 4:57 PM

Feedback

# re: Custom Collections: Collection&lt;T&gt; and BindingList&lt;T&gt; 9/4/2006 2:03 PM Jonathan Mitchell

Thanks Sean

I was refatoring a class from List<T> to BindingList<T> and was lamenting my loss of List<T>.Sort.

Googled and here I am.

I had presumed that BindingList<T> inherited from List<T> not Collection<T>.

Couldn't be better.

Thanks again.