INotifyPropertyChanged and ObservableCollection

In case of binding scenarios, earlier, developers had to write code to make sure that UI and internal objects are all in sync with each other. With INotifyPropertyChanged interface and ObservableCollection<T>, it has become simple to keep those layers in sync.

INotifyPropertyChanged
  • This interface can be implemented to notify to the client that some property has changed. Its mostly used in the case of databinding scenarios.
  • Its usage is demonstrated below:
public partial class A01NotifyPropertyChanged : Window
    {
        Person p;
        public A01NotifyPropertyChanged()
        {
            InitializeComponent();
            p = new Person { Age = 29 };
            DataContext = p;
        }

        private void changeItemBtn_Click(object sender, RoutedEventArgs e)
        {
            p.Age += 1;
        }
    }

    public class Person : INotifyPropertyChanged
    {
        private int m_age;
        public int Age 
        {
            get
            {
                return m_age;
            }
            set
            {
                if (value != m_age)
                {
                    m_age = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("Age"));
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
The corresponding XAML file looks like this:
<Grid>
        <StackPanel>
            <TextBox Text="{Binding Age}"/>
            <Button Content="Increase By 1" Name="changeItemBtn" Click="changeItemBtn_Click" />
        </StackPanel>
    </Grid>
In this code, every time the button is clicked, the age is increased by 1. However notice that we have not written any code to update the UI. Since the Person class implements the INotifyPropertyChanged event, the UI, which in this case is the textbox, automatically gets updated.


ObservableCollection<T>
  • Similar to INotifyPropertyChanged, there is another interface named INotifyCollectionChanged, which does the same thing but on collections.
  • However, instead of implementing INotifyCollectionChanged, we are already provided with ObservableCollection<T> which implements both INotifyCollectionChanged and INotifyPropertyChanged.
  • The purpose of this collection is to notify the client about additions, updates and deletes to the collection.
  • Its usage is demonstrated below:
ObservableCollection<string> tasks = new ObservableCollection<string>();
        public A04ObservableCollection()
        {
            InitializeComponent();
            lv.ItemsSource = tasks;
        }

        private void btn_Click(object sender, RoutedEventArgs e)
        {
            if(!string.IsNullOrEmpty(tb.Text.Trim()))
                tasks.Add(tb.Text);
        }

        private void btnRemove_Click(object sender, RoutedEventArgs e)
        {
            string selectedName = lv.SelectedItem as string;
            tasks.Remove(selectedName);
        }
The corresponding XAML file looks like this-
<Grid>
        <StackPanel>
            <Label Name="lbl" Content="To Do List:"/>
            <TextBox Name="tb" Margin="3"/>
            <ListView Name="lv" Margin="3"/>
            <Button Name="btn" Margin="3" Content="Add Task to List" Click="btn_Click"/>
            <Button Name="btnRemove" Margin="3" Content="Remove Selected Task" Click="btnRemove_Click"/>
        </StackPanel>
    </Grid>
In this example-
  • We have an ObservableCollection called tasks and all we have done to bind it to UI is to assign the ItemsSource property of listview to the ObservableCollection.
  • Everytime an item is added, changed or deleted, ObservableCollection notifies the consumer automatically. This ensures that the UI gets updated automatically.

No comments: