Posts Tagged ‘INotifyPropertyChanged’

C# .Net – Using INotifyPropertyChanged with databound classes

March 23, 2010

In the previous blog DataBinding using BindingList<> we bound a list of Contact class objects to a data grid.

One problem with that implementation was if a property on the bound object was updated via logic, rather than via the user interface, then the grid would fail to “Notice” the change.

public class Contact {
    public int ID { get; set; }
    public string Name { get; set; }
}

[TestMethod]
public void ContactChangedFromCode() {

    BindingList<Contact> contacts = new BindingList<Contact>() {
        new Contact() { ID = 1, Name = "Mike" },
        new Contact() { ID = 2, Name = "Joe" }};

    Form frm = new Form();
    DataGrid grid = new DataGrid() { Dock = DockStyle.Fill, DataSource = contacts };
    frm.Controls.Add(grid);
    frm.Show();

    // Wait for a second for (int i = 1; i < 1000; i++) {
        System.Windows.Forms.Application.DoEvents();
        System.Threading.Thread.Sleep(1); // Sleep for a bit }

    // Updating an entry from Code. contacts[0].Name = "Mike Coxeter";

    // Wait for 5 seconds for (int i = 1; i < 5000; i++) {
        System.Windows.Forms.Application.DoEvents();
        System.Threading.Thread.Sleep(1); // Sleep for a bit }

}
This example shows a grid which does NOT reflect the change of name from Code.

By implementing the INotifyPropertyChanged interface on the Contact class then the grid will respond to changes to properties.

public class Contact : INotifyPropertyChanged {
    int id = 0;
    public int ID {
        get { return id; }
        set {
            id = value;
            onPropertyChanged("ID");
        }
    }
    string name = string.Empty;
    public string Name {
        get { return name; }
        set {
            name = value;
            onPropertyChanged("Name");
        }
    }

    void onPropertyChanged( string propertyName ) {
        if (PropertyChanged != null) {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #region INotifyPropertyChanged implementation
    public event PropertyChangedEventHandler PropertyChanged;
    #endregion }

Now if ContactChangedFromCode() is re-run then the grid will update as expected.