WPF Simplified Part 14: INotifyPropertyChanged and ObservableCollection

When data-binding, we want changes to the source (data bound property/collection) to be reflected in the UI. Fortunately WPF gives us some easy ways to keep the UI updated of data changes.

Consider the simple XAML,

<Grid>
    <Grid.RowDefinitions><RowDefinition /><RowDefinition /></Grid.RowDefinitions>
    <!-- Data bound text block -->
    <TextBlock x:Name="MyTextBlock" Height="30" Width="110" Text="{Binding Name}" />
    <!-- Button to change to bound property -->
    <Button Grid.Row="1" Height="30" Width="110" Content="Update" Click="MyButton_Click" />
</Grid>

And the simple class,

        public class Person { public string Name { get; set; } }

We’ll data bind like this,

        Person person;

        public Window1() {
            InitializeComponent();

            person = new Person() { Name = "John" };
            
            // Data bind Window1 to the person object
            // Or we could choose to data bind to the TextBlock directly,
            // this.MyTextBlock.DataContext = person;
            this.DataContext = person;
        }

        private void MyButton_Click(object sender, RoutedEventArgs e) {
            // Change the data bound object's data bound property
            person.Name = "Locke";
        }

When you click the button, nothing happens, the UI isn’t notified that the bound property has changed. There are two ways to fix this,

1. Implement INotifyPropertyChanged:

Implement the Person class like this,

public class Person : INotifyPropertyChanged {
    private string name;

    public string Name {
        get { return name; } 
        set {
            name = value;
            NotifyPropertyChanged("Name");
        } 
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(string name) {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
}


Now clicking the button updates the UI and the TextBlock changes to “Locke”. See here for best practices for implementing INotifyPropertyChanged.

2. Change the property to a Dependency Property:

Implement the property (Name) backed by a dependency property (NameProperty) instead of backed by a field (name) as we previously did. Note that Person class will have to be derived from DependencyObject in this case.

public class Person : System.Windows.DependencyObject {
    public static DependencyProperty NameProperty 
                = DependencyProperty.Register("Name", typeof(string), typeof(Person));
 
    public string Name {
        get { return (string)GetValue(NameProperty); }
        set { SetValue(NameProperty, value); }
    }
}

We have looked at how data bound properties can update the UI, let’s also look at collections, consider that XAML,

<Grid>
    <Grid.RowDefinitions><RowDefinition /><RowDefinition /></Grid.RowDefinitions>
    <!-- Data bound list view –>
    <ListView x:Name="MyListView" DisplayMemberPath="Name" />
    <!-- Button to change the bound collection -->
    <Button Grid.Row="1" Height="30" Width="80" Content="Change" Click="Button_Click" />       
</Grid>

and the Person class,

    public class Person { public string Name { get; set; } }

Let’s data bind a collection of Person to the ListView, like this,

    List<Person> people = new List<Person>()
 
    public Window1() {
        InitializeComponent();

        people.Add(new Person() { Name = "John" });
        people.Add(new Person() { Name = "Jack" });

        // Data bind to the listview,
        this.MyListView.ItemsSource = people;
    }
    private void Button_Click(object sender, RoutedEventArgs e) {
        // Change the data bound collection
        people.Add(new Person { Name = "Jacob" });
    }

When we click the button, the UI doesn’t update. This is because the collection List<> doesn’t implement INotifyPropertyChanged and INotifyCollectionChanged. Luckily, the ObservableCollection does, so simply changing people to an ObservableCollection instance does the trick.

    ObservableCollection<Person> people = new ObservableCollection<Person>();

Advertisements

About soumya chattopadhyay
I live and work in Seattle, WA. I work with Microsoft technologies, and I'm especially interested in C#.

5 Responses to WPF Simplified Part 14: INotifyPropertyChanged and ObservableCollection

  1. Pingback: WPF Simplified Series « I.Net

  2. John says:

    This is a good explanation using a simple example. Concise and easy to follow.

    Thanks…

    John

  3. Vivek Vijayarajan says:

    Good one man nice explanation.

    Its hard to find some good solutions like this.

    Keep Rocking!!!

  4. Taras says:

    Thanks…

  5. MD Rana says:

    i can not solve please help add me in skype my id is rakibahamed111

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: