I Notify When Property Changes – Data Binding Reloaded

On my last post, what I said was pretty basic stuffs on data binding. Now I need to Nerd Up a bit. I mean today we’re gonna take a bit deeper dive into data bindings.  So, if you in case missed the last one on data binding, kindly read my last post on data binding.

So, as this is only a continuation, lets not reinvent the wheel. We’re gonna use the same PersonModel class we used last day because that’s really simple.

Before we get started, let’s get to know someone and his name is INotifyPropertyChanged. Before you get scared, lemme tell you something. This guy holds a very important key of MVVM pattern and practically he does a huge deal of heavy work. Now you might ask what the hell does he do that makes him so important? :S
Now if you believe you dont want to waste your time listening to me saying baby stuff, you can go here and get it by yourself, no baby stuff, rock solid geek material.

Now for the ones who prefer it from me, let me clarify stuff for you in the easiest way possible. The easiest way would be he’s a notifier, practically a mailman who rings your doorbell every time you get a mail, or your fire alarm, who sees a little fire and fies you. If you carefully see, all of these characters do one and one thing in common. They notify you when something important (a very property around you) changes. So, if you are an object of a certain class and you want to know when someone changes one of your property, who you should call? Yes, you should call INotifyPropertyChanged. Clear?

Now, wait wait? how? Call? Is he a method? Look at the name, the name starts with an capital “I”, that means he is an interface, you have to implement him on the class you want to.   So, lets see! Shall we? We’re using our PersonModel class from previous tutorial.

class PersonModel: INotifyPropertyChanged
    {

        private string _name;
        private string _age;
        private string _height;

        public string Name
        {
            get { return _name; }
            set
            {
                if (_name != value)
                {
                    _name = value;
                    NotifyPropertyChanged("Name");
                }
            }
        }

        public string Age
        {
            get { return _age; }
            set
            {
                if (_age != value)
                {
                    _age = value;
                    NotifyPropertyChanged("Age");
                }
            }
        }
        public string Height
        {
            get { return _height; }
            set
            {
                if (_height != value)
                {
                    _height = value;
                    NotifyPropertyChanged("Height");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

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

Looks like a lot of change has taken place ha? Well, truth to be told, yes , it kinda did. DONT GET SCARED. Lets see what we did here. Actually if you see closely we didn’t do much, we implemented the INotifyPropertyChanged and included a event named public event PropertyChangedEventHandler PropertyChanged; And you have to write this event every time you implement INotifyPropertyChanged. You might say what if I forget? Fear not! When you have written INotifyPropertyChanged right beside your class name, press ctrl +  . (dot) and you’ll see Visual Studio asking you to implement all its needed to implement! Easy ha?

Capture

So, you see, you practically dont have to remember this one. But what’s an event? :S An event is a certain situation when you want to invoke or do something. Like the change in the property. But you dont know what to do now, you want to decide when it happens. So what do you do? You write an event and when the certain situation comes you write it then.

So, with that out of the way, why did we write a private object of every property we wrote before? Because, we want to see which property changes. So, there’s a private object like _name for the public property “Name”. Now, if you see closely, the public property have get and set methods. In the get method we are returning the private object and in the set method we are checking whether the new value is same as the previous or not, if it is we set it and raise the event, otherwise we do nothing!

W-wait! raise an event? Well, we did write a method named NotifyPropertyChanged. Why? All it does that it checks whether a user has assigned anything to the event we declared before and if its not null, it fires or invokes it. If its null, it does nothing. Simply put if we want to watch any property, all we have to do is assign something to the event PropertyChanged. The NotifyPropertyChanged takes the name of the property and detects who has raised the event. Neat!

Okay, we need action, right? We need to change some property when the application is running, other wise we wont understand. But before we do that, let me ask you something again. Why are we even doing this? Because when the data inside an object changes , I mean the property changes, the view needs to know that it has changed and if it doesn’t know how it would update itself? We can’t bind them every time it changes. Can we? thats where INotifyPropertyChange comes real handy. Because it notifies the view that the data has changed and you sould update yourself too! 😉

Now lets add a button to the view just so we can update the data behind when we want.

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <TextBox Height="70" HorizontalAlignment="Left" Margin="0,130,0,0" Name="Name" Text="{Binding Name}" VerticalAlignment="Top" Width="450" />
            <TextBox Height="72" HorizontalAlignment="Left" Margin="0,206,0,0" Name="Age" Text="{Binding Age}" VerticalAlignment="Top" Width="450" />
            <TextBox Height="72" HorizontalAlignment="Left" Margin="0,284,0,0" Name="Height" Text="{Binding Height}" VerticalAlignment="Top" Width="450" />
            <Button Content="Update Data" Click="Button_Click" Margin="0,361,0,159" ></Button>
        </Grid>

The UI looks like this right now.
UI Changed after update

Now, we added a click event on the button (we will not do this much in MVVM, will tell you later why). Let’s change that so we can update the data of the PersonModel object.

 private void Button_Click(object sender, RoutedEventArgs e)
        {
            _personModel.Name = "Rishad";
            _personModel.Age = "24";
            _personModel.Height = "5.10";
        }

So, lets see whether it works or not, if I click Update Data, will the data in the textblocks change?

wp_ss_20130929_0001

Amazing! It does change! So, you see, that’s where INotifyPropertyChange comes handy. Hey! we didn’t use the event here by ourselves. Well, when it comes to the changes of views you don’t have to worry about that. When you want some changes based on a property you can call that event.

So, until next time, ciao. Next we’ll dig a bit more on binding modes and element binding. I might go for a video next time. I feel I can deliver better there.

Advertisements

Data binding – loaded

Back to code talks, yay! The last two posts were all about my daily adventures and experience (boring! 😡 ). FINALLY, we’re back to talk about code again. Okay, lemme see what I did wrong on the last post. As it seems because of MVVM’s steep learning curve a lot of people complained me they are not getting stuff properly in their head. So, let’s make it going. Shall we? Let’s break down stuffs a bit.

Let’s get into Data Binding a bit more. What’s data binding. If we remember our very own View-Model-ViewModel then data binding is what shows a Model’s properties on view. What am I meaning actually? Lets think of a data source that provides a list of persons to an app’s view. So, the model would contain a person’s basic properties, like name, age, height etc. A very important point to ponder here is model is not always the data source itself, it is the template of data in most of the times. So, its properties gets shown in the view i.e. in this case a person’s name, age, height would be shown. And thats in the simplest sense binding. It allows the view to form a bond with the model. 🙂 Trust me, that’s the simplest way I can describe data binding.

So, for all the people who are reading this, let me utter the words of  Jesse Liberty,

  • Data binding is not hard to understand
  • Neither hard to implement

SO, DONT RUN AWAY MAN! YOU ARE BETTER THAN THIS!

So, lets get into it. As this is one of the posts of my current series of MVVM I would definitely keep it on track of it. Lets start with a very basic view.

 <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="Data Bidning Loaded" Style="{StaticResource PhoneTextNormalStyle}" />
            <TextBlock x:Name="PageTitle" Text="DataBinding" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <TextBox Height="70" HorizontalAlignment="Left" Margin="0,130,0,0" Name="Name" Text="Name" VerticalAlignment="Top" Width="450" />
            <TextBox Height="72" HorizontalAlignment="Left" Margin="0,206,0,0" Name="Age" Text="Age" VerticalAlignment="Top" Width="450" />
            <TextBox Height="72" HorizontalAlignment="Left" Margin="0,284,0,0" Name="Height" Text="Height" VerticalAlignment="Top" Width="450" />
        </Grid>
    </Grid>

Before we get into what we wrote let’s have a peel how it looks

DataBindingSimple1

Pretty basic ha? We need basic for this stage. So, if you look into the view you will see we practically did nothing. We imported three textbox controls and named them Name, Age and Height and filled them up with the same text. Even simple might get blushed seeing this. Cause this is simpler than the word simple. 😛

View is done, next we need a model. It’s gonna be a simple one too. Lets look our simplest Person model.

namespace DataBindingSimple
{
    class PersonModel
    {
        public string Name { get; set; }
        public string Age { get; set; }
        public string Height { get; set; }
    }
}

For the sake of the simplicity we’re gonna use the .cs file attached with the view i.e. the MainPage.xaml.cs here. We’re not gonna create  a seperate viewmodel for now as our purpose is to understand data binding properly first.

Lets see that first

namespace DataBindingSimple
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor

        PersonModel _personModel;

        public MainPage()
        {
            InitializeComponent();
            Loaded += MainPage_Loaded;

        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            _personModel = new PersonModel()
            {
                Name="Prateek",
                Age="23",
                Height="5.5"
            };

            SetDataContext();

        }

        private void SetDataContext()
        {
            ContentPanel.DataContext = _personModel;
        }

    }
}

Well, if we look into what we have just wrote, we’ll see there’s nothing new here. We added a PersonModel object as the DataContext of ContentPanel in the MainPage Loaded event. Wait, wait, wait, DataContext? What on god’s name is that?

To understand the concept of DataContext is to understand where the data comes from to the view. Obviously the data source and what it looks like or what is the template of the data. Of course its our model. Applying  a DataContext to something is to explicitly declare that the data that would be shown in the control comes from that DataContext. If you understand what Im saying then in the simplest sense DataContext is the source of the data. It can be a list, database object, a simple object like we used here. As long as it has data in the template we want , I mean in the model we described, we don’t have to worry about the view. 🙂
So, what we did here, we created a simple PersonModel object and declared it as DataContext of ContentPanel. Why? Because ContentPanel holds the three textboxes we want to show our data. So, the data should go there and as the ContentPanel is the container of those three textboxes it’s awarded the DataContext. Seems a bit clear now?

Is it supposed to work now? Shall we see my name, age and height in the three textboxes in the view now? The answer is obviously NO! We won’t. Why?
BECAUSE WE DIDN’T BIND THE DATA, DUH!

So, lets bind the data, shall we? Lets see how we bind the three properties of PersonModel in the three textboxes in the view. As we will only change the ContentPanel, lets see it below

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <TextBox Height="70" HorizontalAlignment="Left" Margin="0,130,0,0" Name="Name" Text="{Binding Name}" VerticalAlignment="Top" Width="450" />
            <TextBox Height="72" HorizontalAlignment="Left" Margin="0,206,0,0" Name="Age" Text="{Binding Age}" VerticalAlignment="Top" Width="450" />
            <TextBox Height="72" HorizontalAlignment="Left" Margin="0,284,0,0" Name="Height" Text="{Binding Height}" VerticalAlignment="Top" Width="450" />
        </Grid>

The only thing that has changed is the text property of all the three textboxes. As we wanted to show the name property of the model in the first textbox we wrote:

<TextBox Height="70" HorizontalAlignment="Left" Margin="0,130,0,0" Name="Name" Text="{Binding Name}" VerticalAlignment="Top" Width="450" />

Look into the snippet Text={Binding Name}. Here Binding Name means we are binding the name property of the DataContext to the textbox. And what was the DataContext? Yes! The PersonModel object we assigned as DataContext a while ago.

Let’s see whether it works or not.

DataBindingSimple2

Yay! it does! So, you see Data Binding is practically very very easy. All you need to know is where is to bind something and what to bind. 🙂

I really wanted to talk a bit more but as I see long tutorials kind of takes people’s interest away from it now – a – days. So, thats it for today.

Next, we’re gonna talk about

  • Data Binding with INotifyPropertyChanged
  • Data Binding Modes
  • Element Binding
  • Data Converters

Don’t worry, I wont write these in a single one of course, learned my lesson from the last one. I would try to break these up into short ones.

So, until the next one, ciao!

Data Binding in MVVM – Bind views with viewmodels!

if(you_liked_app_philosophy)
start_here;else
goto Serious_talks;

So as per said in my last write up, Im supposed to give a glimpse on how viewmodel talks with views and how models supply them data. Im now gonna get straight back to the car scenario. Think of that car again. We had three parts, the engine (model), the body (view) and the driver (the viewmodel). You drive well, your car seems nice and clean, you roughhouse, eh! you might make it work on the outside but someday when you feel like upgrading that stuff, the only thing you’re gonna say, “what on earth did I do there”? If you ask me how do I know this? Brother I did the same mistake over and over again. (Yes, as per description of insanity from Far Cry 3, I was insane!)

So, the part I want to say here, your cars body will say how you drive. If it’s nice shiny and clean it says you’re a clear one, if it isn’t it says something else. So, the body (view) shows the signs you(viewmodel) leave on it. And how you bind it? Press the buzzer please!

“Data Binding” you say sire? You’re exactly right me lord.

Let’s Dive in.

Serious_talks:

Okay the serious stuff is in. I started with a pretty standard XAML (I believe you’ve met with standard Windows Phone development process, if you didn’t, you should and come back here). I added a panorama control, renamed it’s title to Star Cineplex. I added two panoramaitem control to cover “Now Showing” and “Coming Soon”. Pretty basic stuff actually. So, the xaml looks like below:

<phone:PhoneApplicationPage
x:Class="Star_Cineplex.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">

<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>

</Grid.RowDefinitions>

<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<phone:Panorama Title="Star Cineplex">
<phone:PanoramaItem Header="Now Showing">
<ListBox Name="NowShowingList"  >

</ListBox>
</phone:PanoramaItem>
<phone:PanoramaItem Header="Coming Soon">

</phone:PanoramaItem>
</phone:Panorama>

</Grid>

</Grid>

</phone:PhoneApplicationPage>

So I guess it looks pretty simple to you.  You might want to look into the Listbox named “NowShowingList” as magic is gonna happen there. So, yes, the viewmodel mostly talks with view through data binding. . And Im not gonna tell much on data binding, so you should go for some basic data binding tutorials first. Without it, all of these would seem nonsense to you. True Story!

Let’s provide a dummy model. The model is nothing but a class who states how the actual data is represented. Let’s make a very simple Movie class. Shall we?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Star_Cineplex
{
    class Movie: INotifyPropertyChanged
    {
        private string name;
        private int year;

        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                if (this.name != value)
                {
                    this.name = value;
                    this.RaisePropertyChanged("Name");
                }
            }
        }

        public int Year
        {
            get
            {
                return this.year;
            }
            set
            {
                if (this.year != value)
                {
                    this.year = value;
                    this.RaisePropertyChanged("Year");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    }
}

Lets have a quick talk on the model then. The first thing you need to notice is the use of the INotifyPropertyChanged interface use. This very interface works as a secret serum for almost everything written on a MVVM app. You might ask why? This guy pokes you when a property changes its value in the class its implemented. Like if something changes the year property of the Movie class, this guy will jump up and say “Hello, somebody just changed the year property, care to do something?” Funny, ha? As funny as it sounds, believe me, this is one of the guys who you would see most in MVVM. So, lets have a lil discussion on this interface.

INotifyPropertyChanged interface basically raises an event named PropertyChanged. All you have to do is declare the event explicitly along with a method that will be executed generally for all properties that are monitored for a change. The method is optional if you’re cool with anonymous functions or lambda expressions. 😉

If you’re not, don’t leave. I’m even breaking it more up for you. You see in the set {} method of the property Year and Name whenever I found a change in the value I invoked the RaisePropertyChanged method to invoke the event to let the user know something has changed the property. We’ll actually go for a template or definite interfaces for models later so we don’t have to do this every time we write a model. But that’s later. Let’s focus on this simple area right now. 🙂

So, the model is pretty simple as it seems, so for now let’s forget the model, we’re gonna provide sample data here somehow to test how things work within the view and viewmodel. So, we need a viewmodel first. Don’t we? I’m posting a very basic viewmodel here. Later we would organize and sanitize the workflow more so we can extend stuff fast. But for now, for clarity’s sake let’s keep it very simple. Don’t worry the explanation comes just after. I believe the code talks more to a developer than anything.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using System.Windows.Input;

namespace Star_Cineplex
{
    class MovieViewModel
    {
        private ObservableCollection<Movie> movieDataSource;
        private ICommand loadDataCommand;

        public MovieViewModel()
        {
            this.movieDataSource = new ObservableCollection<Movie>();
            LoadData();
        }

        private void LoadData()
        {
            this.movieDataSource.Add(new Movie() { Name="Despicable Me 2", Year=2013});
            this.movieDataSource.Add(new Movie() { Name = "Man Of Steel", Year = 2013 });
            this.movieDataSource.Add(new Movie() { Name = "Wolverine", Year = 2013 });
        }

        public ObservableCollection<Movie> MovieDataSource
        {
            get
            {
                if (this.movieDataSource == null)
                {
                    this.movieDataSource = new ObservableCollection<Movie>();
                }
                return this.movieDataSource;
            }
        }

    }
}

I believe this is by far the simplest Viewmodel you can write. You see, all I did is I populated the MovieDataSource list with some data.

So, if you read the link I gave you before on Data Binding you’d might ask why Im not yet binding? Let’s do that! Remember the ListBox named “NowShowingList”? Change it into this one below:

<ListBox Name="NowShowingList" ItemSource={Binding MovieDataSource}  >
<ListBox.ItemTemplate>
 <DataTemplate >
 <StackPanel>
 <TextBlock Text="{Binding Name}" FontSize="{StaticResource PhoneFontSizeLarge}"></TextBlock>
 <TextBlock Text="{Binding Year}"></TextBlock>
 </StackPanel>
 </DataTemplate>
</ListBox.ItemTemplate>
</Listbox>

Wait, wait, wait! What did I do here? The first change you will see that I declared the itemsource of the listbox and I binded it with MovieDataSource, the one in our ViewModel!
This is done to show the movie list we created into the ListBox.

You might ask why did I use ObservableCollection? The interesting part is whenever you bind an ObservableCollection object as a ListBox’s itemsource, you dont have to worry about any changes in the list, the UI will adjust the changes automatically, no hassle needed! 😀 So, I mean if somehow the ObservableCollection gets bigger, the list in the UI will automatically grow bigger! So, if you add/remove a movie in the MovieDataSource, the NowShowingList ListBox will automatically grow bigger.

And I defined a data template to show the data. The datatemplate actually defines how each of your rows of your listbox will look like. I only used two texblocks here. And see! I binded the first one with Name and the second one with Year! Why? Because remember what was in the MovieDataSource? Yes, our model movie objects. It had two properties, Name and Year. We want both of them in our list. So, we binded both of them.

Now the question rises. Is this all? Aren’t we forgetting something?

Yes we are actually forgetting one thing. Kindly open the MainPage.xaml.cs and add the DataContext like this.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Star_Cineplex.Resources;

namespace Star_Cineplex
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();
            this.DataContext = new MovieViewModel();

        }

    }
}

So, what is the DataContext? the DataContext is the glue that holds them all. DataContext is usually defined by ViewModels as they provide the representable data to the view. I could’ve shown you many ways to bind data to the view but choosing a very simple example like this had only one objective and that is to let you know in MVVM to bind your view to viewmodel you only have to assign the DataContext. The rest is a breeze!

One other thing! I used a INotifyPropertyChanged in my model but never actually used it. We’ll continue this journey a bit more with ICommand usage and of course more binding usage with INotifyPropertyChanged interface in the upcoming ones.

Oh! This is how it looks now!

Screenshot

So, until next time, goodbye pals!