Freigeben über


Data Binding Part 4- Observable Collection

In Part 1 of this series I covered the basic theoretical idea behind data binding, and in Part 2, we got a little more concrete with a hands on example in code.  We created a Movie class, then bound the three properties of that object (title, rating, year), to our UI in both Windows and Windows Phone projects using a Universal Windows App.  Then, in Part 3, we took a look at implementing the INotifyPropertyChanged interface and the difference in OneWay and TwoWay binding.  Now, we are going to take it one step further.  Instead of just displaying one movie to our UI, we are going to bind to a list of movies using a ListView and ObservableCollection.

So, first off, what is an ObservableCollection.  According to MSDN, it “represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed”.  There are two key phrases here that jump out to me, “dynamic data collection”, and “provides notifications when items get added…”.  Let’s take a look at the first part, “dynamic data collection”.  This sounds a lot like a list, doesn’t it?  A collection of generic type <T> objects, meaning that it can keep a collection of any objects, including ones that we create such as our Movie class. 

Now, let’s turn to the second phrase.  Coincidentally, it sounds a lot like the purpose of the INotifyPropertyChanged Interface that we used for our Movie class in Part 3.  Well, that’s because they serve a similar purpose in data binding.  In fact the ObservableCollection class is a built in implementation of a data collection that implements INotifyPropertyChanged.  The point of this is that if we create an instance of ObservableCollection<T>, it will automatically be able to provide notifications for updates to the collection for data binding.  If we instead used a simple List, we would have to do the notification part manually.  However, keep in mind that ObservableCollection itself only notifies for changes to the collection, not for property changes of the individual objects in the collection.   Since we have already taken care of this in our Movie class, we  are good to go, just something to keep in mind.  All in all, I say we go for the easier (less work) route and use ObservableCollection<T> to store the list of our Movie objects.

Now that we have our plan, let’s get started.  First, we need to create a new class for our data source, the ObservableCollection of Movie objects.  We can add a new class to our Shared project and call it MoviesDataSource.cs.  Since this class doesn’t need to do much more than store our Movie objects, we can make it derive from ObservableCollection<Movie>.  Then we can create a method called LoadData() where we add some static data to our collection and call that method from within our constructor.  Here’s what I’m talking about.

class MoviesDataSource : ObservableCollection<Movie>
    {
        public MoviesDataSource()
        {
            loadData();
        }

        private void loadData()
        {
            this.Add(new Movie { Title = "X-Men", Rating = "PG13", Year = "2014" });
             this.Add(new Movie { Title = "Divergent", Rating = "PG13", Year = "2014" });
            this.Add(new Movie { Title = "Draft Day", Rating = "PG13", Year = "2014" });
             this.Add(new Movie { Title = "Rio 2", Rating = "G", Year = "2014" });
            this.Add(new Movie { Title = "Blended", Rating = "PG13", Year = "2014" });
         }
    }

Again, this is using Static data.  We will cover dynamic data eventually, but for now this will suffice.  Anyways, we now have our MoviesDataSource class, so we need to update our UI to include a ListView.  We can basically scratch everything we have in our MainPage.xaml except for the underlying grid.  Within the grid we just want to add a simple ListView.  I have created a DataTemplate for this ListView, which defines what each item in the ListView should look like (remember the three binding Textblocks?).  If you don't know how to create and reference styles and templates, you can read my post on Custom Styles.  My DataTemplate looks like this.

<DataTemplate x:Key="ListViewDataTemplate">
        < StackPanel>
            < TextBlock Text="{Binding Title}" Style="{StaticResource TextStyle}"/>
            < TextBlock Text="{Binding Rating}" Style="{StaticResource TextStyle}" />
             <TextBlock Text="{Binding Year}" Style="{StaticResource TextStyle}" />
        </StackPanel>
</DataTemplate>

Now, all I need to do within the ListView tag is give it a name and reference my DataTemplate.  Looks like this.

<ListView ItemTemplate="{StaticResource ListViewDataTemplate}" x:Name="ListView"/>

Our ListView is created and thanks to the DataTemplate I defined above, we still have the three Textblocks bound to the three different properties of a Movie object.  The last step here is to set the ItemsSource property of the ListView dynamically to an instance of the MoviesDataSource class.  You might be wondering why we are now using the ItemsSource property instead of the DataContext property we used before.  It’s pretty simple, ItemsSource is used for collections, and DataContext is used for one object.

Back in our code behind, we can keep our MainPage_Loaded event handler and scratch everything else.  We just need to declare an instance of MoviesDataSource, initialize it in the loaded event handler, and then set the ItemsSource property of our ListView to that instance.  My code now looks like this.

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

       void MainPage_Loaded(object sender, RoutedEventArgs e)
       {
           movies = new MoviesDataSource();
           ListView.ItemsSource = movies;
       }
   }

Here comes the moment of truth.  Run your app and hopefully it looks like this.

Screenshot (214)

Run it in the Windows phone emulator and you should see the same thing.

Capture7

There we have it, the list of our movies.  Granted this doesn’t look over pleasingly to the eye, but keep in mind I am no UI expert and this isn't a tutorial on pleasant looking apps :)  I mentioned it earlier but the next and final post in this series will cover using dynamic data.  We will get the data from the RottenTomatoes API so stayed tuned for Part 5.

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

Comments

  • Anonymous
    June 20, 2014
    Great! Thank you very much.

  • Anonymous
    November 05, 2015
    As you would to change an item from this collection ? response: polianadias@outlook.com