Data Binding With INotifyPropertyChanged Interface

Introduction

Welcome again! Today we'll talk about a little bit advanced topic, Data Binding. It's really useful when you've massively structured code and you've to handle a lot of data, not like our typical controls. For example:

textBox1.Text = “Hello, world!”;

Data Binding is nothing but creating a “ViewModel” class or you can name it as you wish, that actually contains the data. One more important thing, you must follow in the Data Binding control is INotifyPropertyChanged. It actually gives you an alert, when a property value is changed. Just like hey there, “I'm changed.” We'll return to it later.

Various Binding Modes

There are a number of various binding modes, as defined in the BindingMode enumeration:

  • TwoWay: Changes to the UI or model automatically updates the other. This is used for editable forms or other interactive scenarios.

  • OneWay: Updates the UI when the model changes. This is appropriate for read-only controls populated from data.

  • OneTime: Updates the UI when the application starts or when the data context changes. This is used when the source data is static/does not change.

  • OneWayToSource: Changes to the UI update the model.

  • Default: Uses the default mode for the specific binding target (UI control). This differs based on the control.

Objects that take part in OneWay or TwoWay binding must implement the “INotifyPropertyChanged” interface. Thus interface requires only that the object publishes the “PropertyChanged” event:

  1. public class ItemViewModel : INotifyPropertyChanged  
  2. {  
  3.       public event PropertyChangedEventHandler PropertyChanged;  
  4.       ...  
  5. }  
Listing 1

The object must fire the “PropertyChanged” event whenever the value of one of its public properties changes.

So, first of all we'd like to implement our “ViewModel” class, that will contain our data properties.

Adding a “ItemViewModel” class

Add a new class and provide it a name “ItemViewModel”.

add new class
Figure 1

Now, we need to declare our private properties what we want to do and make public get and set methods. It's really a bad idea to declare your variables public. So, we've declared it private but work with it internally public.

There are two types of “INotifyPropertyChanged” implementations. One is Non-Optimal and the other is Optimal. Let's see how the Non-Optimal implementation works first.
  1. public class ItemViewModel : INotifyPropertyChanged  
  2. {  
  3.     // Properties  
  4.     private string _manufacturer;  
  5.     private string _model;  
  6.     private string _color;  
  7.     private int _year;  
  8.   
  9.     public string manufacturer  
  10.     {  
  11.         get { return _manufacturer; }  
  12.   
  13.         set  
  14.         {  
  15.             _manufacturer = value;  
  16.             NotifyPropertyChanged("manufacturer");  
  17.         }  
  18.     }  
  19.   
  20.     public string model  
  21.     {  
  22.         get { return _model; }  
  23.   
  24.         set  
  25.         {  
  26.             _model = value;  
  27.             NotifyPropertyChanged("model");  
  28.         }  
  29.     }  
  30.   
  31.     public string color  
  32.     {  
  33.         get { return _color; }  
  34.         set  
  35.         {  
  36.             _color = value;  
  37.             NotifyPropertyChanged("color");  
  38.         }  
  39.     }  
  40.   
  41.     public int year  
  42.     {  
  43.         get { return _year; }  
  44.         set  
  45.         {  
  46.             _year = value;  
  47.             NotifyPropertyChanged("year");  
  48.         }  
  49.     }  
  50.   
  51.     // Property Change Logic  
  52.     public event PropertyChangedEventHandler PropertyChanged;  
  53.   
  54.     private void NotifyPropertyChanged(string propertyName)  
  55.     {  
  56.         if (PropertyChanged != null)  
  57.         {  
  58.             PropertyChanged(thisnew PropertyChangedEventArgs(propertyName));  
  59.         }  
  60.     }  
  61. }  
Listing 2

Here, we've declare our four private properties, actually a car's attributes and most importantly in the setter whenever the value changes we call a method called “NotifyPropertyChanged“ (“manufacturer”), that fires that property changed event. And gives the name of that property. It's kind of error-prone because what we use is “Magic Strings”. It's not actually good to hard-cod a given new name of your property.

Optimal ViewModel Implementation

Now, let's see our Optimal ViewModel implementation.
  1. public class ItemViewModel : INotifyPropertyChanged  
  2. {  
  3.     // Properties  
  4.     private string _manufacturer;  
  5.     private string _model;  
  6.     private string _color;  
  7.     private int _year;  
  8.   
  9.     public string manufacturer  
  10.     {  
  11.         get { return _manufacturer; }  
  12.   
  13.         set { this.SetProperty(ref this._manufacturer, value); }  
  14.     }  
  15.   
  16.     public string model  
  17.     {  
  18.         get { return _model; }  
  19.   
  20.         set { this.SetProperty(ref this._model, value); }  
  21.     }  
  22.   
  23.     public string color  
  24.     {  
  25.         get { return _color; }  
  26.   
  27.         set { this.SetProperty(ref this._color, value); }  
  28.     }  
  29.   
  30.     public int year  
  31.     {  
  32.         get { return _year; }  
  33.   
  34.         set { this.SetProperty(ref this._year, value); }  
  35.     }  
  36.   
  37.   
  38.     // Property Change Logic  
  39.     public event PropertyChangedEventHandler PropertyChanged;  
  40.   
  41.     protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)  
  42.     {  
  43.         if (object.Equals(storage, value)) return false;  
  44.         storage = value;  
  45.         this.OnPropertyChaned(propertyName);  
  46.         return true;  
  47.     }  
  48.   
  49.     private void OnPropertyChaned(string propertyName)  
  50.     {  
  51.         var eventHandler = this.PropertyChanged;  
  52.         if (eventHandler != null)  
  53.             eventHandler(thisnew PropertyChangedEventArgs(propertyName));  
  54.     }  
  55. }  
Listing 3

And you've noticed that it's a kinda nice reflection tool to change the name of your property, that will do nicely through all of your app. It works similarly with a Non-Optimal “ViewModel” but you must change the value of your property automatically and fire the “PropertyChanged” event whenever the value of one of its public properties changes.

Designing UI

So, our “ViewModel” implementation is okay now. Now, we'll move to design our app, that will show four properties of our “ItemViewModel” class. Let's use four TextBlocks and a Button. You can design as you wish to do so. The sample XAML UI code is given below.
  1. <!--TODO: Content should be placed within the following grid-->  
  2. <Grid Grid.Row="1" x:Name="ContentRoot" Margin="19,9.5,19,0">  
  3.     <TextBlock Height="50"  
  4.                HorizontalAlignment="Left"  
  5.                Margin="10,10,0,0"  
  6.                Name="manufacturerBlock"  
  7.                Text="{Binding manufacturer,Mode=TwoWay}"   
  8.                VerticalAlignment="Top"   
  9.                Width="342" FontSize="24"/>  
  10.     <TextBlock Height="50"   
  11.                HorizontalAlignment="Left"  
  12.                Margin="10,65,0,0"  
  13.                Name="modelBlock"  
  14.                Text="{Binding model,Mode=TwoWay}"  
  15.                VerticalAlignment="Top"  
  16.                Width="342" FontSize="24"/>  
  17.     <TextBlock Height="50"  
  18.                HorizontalAlignment="Left"  
  19.                Margin="10,120,0,0"  
  20.                Name="colorBlock"  
  21.                Text="{Binding color,Mode=TwoWay}"  
  22.                VerticalAlignment="Top"  
  23.                Width="342" FontSize="24"/>  
  24.     <TextBlock Height="50"  
  25.                  HorizontalAlignment="Left"  
  26.                  Margin="10,175,0,0"  
  27.                  x:Name="yearBlock"  
  28.                  Text="{Binding year, Mode=TwoWay}"  
  29.                  VerticalAlignment="Top"  
  30.                  Width="342" FontSize="24"/>  
  31.     <Button Content="Update"  
  32.             Height="50"  
  33.             HorizontalAlignment="Left"  
  34.             Margin="202,443,0,0"  
  35.             Name="updateButton"  
  36.             VerticalAlignment="Top"  
  37.             Width="150"  
  38.             Click="updateBtn_Click" />  
  39. </Grid>  
Listing 4

Here, we've used the TwoWay mode, because we will update our databound UI elements in the XAML runtime.

Backend C# Coode

Now, let's look inside of our “MainPage.xaml.cs” class.
  1. public sealed partial class MainPage : Page  
  2. {  
  3.       ItemViewModel _itemViewModel;  
  4.       ...  
  5. }  
Listing 5

Put this line of code at the top of our constructor. It creates an object of our “ItemViewModel” class.
  1. // Constructor  
  2. public MainPage()  
  3. {  
  4.       this.InitializeComponent();  
  5.   
  6.       Loaded += MainPage_Loaded;  
  7.       ...  
  8. }  
Listing 6

Update the constructor with the “MainPage_Loaded” method, because when you run the application it'll call the method to display the data.

Now, implement the “MainPage_Loaded” method.
  1. // Constructor  
  2. public MainPage()  
  3. {  
  4.     this.InitializeComponent();  
  5.    
  6.     Loaded += MainPage_Loaded;  
  7. ...  
  8. }  
Listing 7

So, we created a new “ItemViewModel” object and bound our data in the “ItemViewModel” class and set the data context by calling the “setDataContext” method.
  1. private void setDataContext()  
  2. {  
  3.       ContentRoot.DataContext = _itemViewModel;  
  4. }  
Listing 8

What it does is it sets up our data in the main Grid of our XAML UI. Here, “ContentRoot” is the name of our main Grid.
  1. // utility method that changes the PhoneModel properties  
  2. private void setItemProperties(String manufacturer, String model, String color, int year)  
  3. {  
  4.       _itemViewModel.manufacturer = manufacturer;  
  5.       _itemViewModel.model = model;  
  6.       _itemViewModel.color = color;  
  7.       _itemViewModel.year = year;  
  8. }  
Listing 9

It's kinda nice, that you don't need to worry about showing your data. Which is string and which is int, you don't need to bother about it. Just make a reference of your data, that's it.
When we press our Update Button, it'll do the work for us.
  1. // called when update button is clicked  
  2. private void updateBtn_Click(object sender, RoutedEventArgs e)  
  3. {  
  4.       setItemProperties("Ford""Mustang GT""Blue", 2010);  
  5. }  
Listing 10

It calls the “setItemProperties” method and es the following data to it. Really simple, isn't it?

Running the Application

Now, if you run the application, it'll look exactly like this.

data binding

Summary

That's it. I hope you understand the basics of “DataBinding” and the “INotifyPropertyChanged Interface”. So, make your app more awesome with these features. I'll be here with some new topics soon. Until then good bye. Have a nice day.

Happy Coding!

Read the original article at: http://bit.ly/1t2oND4 


Similar Articles