Freigeben über


Data Binding Part 2- Movie Ex. Hands On

In Part 1 of this series on Data Binding, I tried to provide a high level understanding; what it does, how it works,  and how it can benefit the developer.  I talked about the four different components that make up a typical binding (binding target object, target property, binding source, and path to value).  I also mentioned the four different types of data binding options that are available to the developer (OneWay, TwoWay, OneWayToSource, and OneTime).  If you need a refresher on the basic concepts and definitions, take a look back at  Part 1.  Otherwise, I want to now transition to some actual coding of the theoretical example mentioned previously.  I will be using Visual Studio with XAML and C#.

Just as a refresher, the theoretical example that we talked about in Part 1 was about binding movie data (title, rating, and year) to three different TextBlocks on the UI.  To do this, we will create a simple Movie class that will containing those three different properties.  We will then create an instance of a movie object and bind that object to our UI.  Also note that we will be using the new Universal Windows App project to take advantage of the latest and greatest in Windows app development :).

First things first.  Create a new Blank Universal App and call it whatever you want.  Let’s now create our movie class and put it inside of our Shared project, so that it can be referenced by both the Windows and Windows Phone projects.  To do this, right click on the shared project folder and click Add->New Item, select class and call it Movie.cs.  Again, this movie class will only have three properties, all strings.  Since it is a relatively simple class I wont give to much instruction there, but here is my code.

class Movie
    {
        private string title;
        private string rating;
        private string year;
        public string Title
        {
            get{return title;}
            set{title=value;}
        }
        public string Rating
        {
            get { return rating; }
             set { rating = value; }
        }
        public string Year
        {
            get { return year; }
             set { year = value; }
        }
    }

Now we need to create our UI of three different text blocks, one for each of the properties of the movie class.  This part is pretty simple also.  We will just add a stack panel with three textblocks inside of our initial grid. Let’s do this first in the Windows project, so open up its MainPage.xaml and add the stack panel.  I am going to add a custom style to my text blocks for the font size and horizontal alignment properties.  If you have never created and use custom styles , you can check out my post on Custom Styles.  You don't have to use this now, but it will save you a little code.

When you create each of the Textblocks we need to tell them what piece of data we are going to bind too.  In other words, we need to define what the “path to value” is.  Since each textblock corresponds to a property of the movies class, we will want to bind the first one to the title property, the second to the rating property, and the third to the year property.  The syntax for declaring this binding, for example with the title property, will look like this, Text= “{Binding Title}".  Here’s my XAML.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        < StackPanel>
            < TextBlock Text="{Binding Title}" Style="{StaticResource TextStyle}"/>
            < TextBlock Text="{Binding Rating}" Style="{StaticResource TextStyle}"/>
             <TextBlock Text="{Binding Year}" Style="{StaticResource TextStyle}"/>
        </StackPanel>
    </Grid>

The next step in this binding will be to set the DataContext of our layout to an instance of a Movie object, and we will do this dynamically in the code behind. Setting the data context of our page is the equivalent of defining the “binding source”.  In other words, the binding statement defines which proprety, the “path to value”, of the the Movie object instance, the “binding source”, to display and bind to.  That said, we need to create an instance of a Movie object, so open up the code behind for our MainPage.

We want to create our Movie object inside of the MainPage_Loaded event handler.  You can create this handler by starting to type “this.loaded+=” inside of the class constructor and pressing tab twice to have Visual Studio take care of the rest for you.  Then, inside of the loaded event handler, create a Movie object and set the title, rating, and year.  The very last thing to do here it to set the data context by using the following, “this.DataContext = movie;”.

Your code behind should now look similar to this.

public sealed partial class MainPage : Page
   {
       Movie movie;
        public MainPage()
       {
           this.InitializeComponent();
           this.Loaded += MainPage_Loaded;
        }

       void MainPage_Loaded(object sender, RoutedEventArgs e)
       {
           movie = new Movie();
            movie.Title = "X-Men Days of Future Past";
            movie.Rating = "PG13";
           movie.Year = "2014";
            this.DataContext = movie;
       }
   }

If you test your app locally now, you should be pleased to see you movie data being displayed on the screen like mine is here.

Screenshot (207)

If you want to transition to testing your Windows Phone project, you could copy and paste the code (inMainPage.xaml and the code behind) that we just wrote in the Windows Project and see the same thing.  However, since we are going to use the same layout for both projects, let’s just copy the MainPage.xaml from the Windows project to the Shared project.  That way as we only make updates to our code once and see it reflected in both projects.  My Solution Explorer now looks like this.

Capture2

Notice that all of the code that we have written so far no resides in the Shared project.  Typically your xaml pages will stay in their respective projects because you want different layouts for phone vs pc and tablet, but in this case our layout is simple enough to where it works the same for both.

Now, switch the target of your project to Windows Phone by going to the target drop-down menu selecting Startup Project->Windows Phone as shown in the screen shot.

Screenshot (208)

Run in the phone emulator and you should see the same data we saw in the Windows 8 version. You can see that mine doesn’t fit perfectly on the screen, which is why typically you would want two different layouts, one for Windows 8 and one for phone.  However, working this way gives us an introduction to Universal Apps as well.  If you feel inclined, feel free to go back to having two separate layout pages, but for the rest of the posts I will just be editing one layout.

Capture4

What we have done so far is make an initial binding to our data. However, if we were to change the Movie object instance dynamically, our UI would not reflect that change.  This is because we are missing one step in our Movie class, implementing the INotifyPropertyChanged interface.  I will cover implementing that interface as well as showing demonstrating the user of TwoWay binding in Part 3.

Feel free to follow me on twitter for upcoming posts! @jquickwit  As always comment with any questions, comments, or concerns below!

Comments

  • Anonymous
    June 08, 2014
    Thank you , lol I just finish reading part 1 and You just came with part 2 :).

  • Anonymous
    June 20, 2014
    James Quick, could you explain why use a event (MainPage_Loaded) instead a function? I'm very beginner I did not understand this. Is it a particularity of Windows Store Apps? Regards

  • Anonymous
    June 20, 2014
    Hey Lucas, I think this is actually more specific to Windows Phone.  According to Nokia documentation, "The best place to perform the binding is when page initialisation completes, in the MainPage_Loaded() event handler as shown below".  This loaded event is triggered after we are sure that the page has been loaded fully, and therefore, after that we can do our data binding.  You could call a function from within the loaded event handler if you wanted to, but since the binding was fairly simple I just left it inside of the event handler.  Does that help?

  • Anonymous
    June 20, 2014
    Yes! Thank you for helping me!