BindingList<T> a new way to bind lists

In .NET 1.1 binding to a list required a lot of work. First you had to inherit from Collection base and implement all of the Collection interfaces so that the caller could add and remove and move through your collection in a type safe way. Then you had to implement IBindingList which afforded your list the ability to keep up to data as a user edited your collection when bound to a grid. When all of this was said and done you had quite a bit of work to do.

public class CustomersList :  CollectionBase, IBindingList
{
    // all of the implementation went here

}

Now in .NET 2.0 this work has been dramatically reduced. A new class BindingList has been added that inherits from Collection and implements IBindingList, IList, ICollection, IEnumerable, ICancelAddNew, IRaiseItemChangedEvents. By having all of this wrapped up for you creating a list of cutomers you can bind to is a simple as:

BindingList customerCollection = new BindingList();

This statement performs what one took many many lines of code. The customerCollection variable can now be bound to a grid and work with in row editing and all of the new features of the DataGridVeiw. Now there are still a few things left to do. First you have to add data to the collection (of course) but one other thing is to have the Customer class implement INotifiyPropertyChanged and IEditableObject. The IEditableObject is the same as before but the INotifyPropertyChanged interface implements a pattern that was originally accomplished by adding a XXXPropertyChanged event for each property in your class. The code below demonstrates the changes. As you can see removing the need for the many XXXPropertyChanged events saves a lot of coding.

  public class Customer : IEditableObject, INotifyPropertyChanged
    {
        private bool editMode = false;
       
        private int number;
        private int _number;

        public int Number
        {
            get { return number; }
            set { number = value; OnPropertyChanged(“Number”); }
        }

        private string name;
        private string _name;

        public string Name
        {
            get { return name; }
            set { name = value; OnPropertyChanged(“Name”); }
        }

        private string street;
        private string _street;

        public string Street
        {
            get { return street; }
            set { street = value; OnPropertyChanged(“Street”); }
        }

        private string city;
        private string _city;

        public string City
        {
            get { return city; }
            set { city = value; OnPropertyChanged(“Street”); }
        }

        private string state;
        private string _state;

        public string State
        {
            get { return state; }
            set { state = value; OnPropertyChanged(“State”); }
        }

        public Customer() { }
       
        public Customer(int number, string name, string street, string city, string state)
        {
            this.number = number;
            this._number = number;
            this.name = name;
            this._name = name;
            this.street = street;
            this._street = street;
            this.city = city;
            this._city = city;
            this.state = state;
            this._state = state;
        }

        #region IEditableObject Members

        public void BeginEdit()
        {
            if (!editMode)
            {
                _number = number;
                _name = name;
                _street = street;
                _city = city;
                _state = state;
            }

            editMode = true;
        }

        public void CancelEdit()
        {
            if (editMode)
            {
                number = _number;
                name = _name;
                street = _street;
                city = _city;
                state = _state;
            }
            editMode = false;
        }

        public void EndEdit()
        {
            editMode = false;
        }

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }

One thought on “BindingList<T> a new way to bind lists

  1. Hi,

    It’s worth mentioning that the handler of INotifyPropertyChanged notifications in BindingList<T> is very poorly implemented. Specifically when the BindingList<T> receives notifications of new object, it compares this object with the previous object that was used for notification. If they are not identical, the binding list does a terrible thing – it runs through ALL objects to get the index of the notifying object.
    Here are more details and explanations how to improve the performance: http://www.blog.dapfor.com/why-bindinglist-is-slow-with-objects-implementing-inotifypropertychanged-interface

    Best regards,

Leave a Reply to Andrei Cancel reply

Your email address will not be published. Required fields are marked *