Xamarin.Forms: ListView Simple MVVM Binding Example

Friday, February 24, 2017



Continuing this series of simple MVVM bindings in Xamarin.Forms. In this tutorial I will make simple ListView binding in XAML.

Run your Visual Studio and create new Xamarin.Forms project, add Views, Models and ViewModels folders.

This will be simple one page app with ListView as a main control on the page/view and we will demonstrate how to make simple MVVM binding in ListView.

Scenario for this demo is: At constructor of ViewModel we will set some default values, and after couple of seconds using web services we will "grab" some other data and store (update) it in our list, and all of this will be inside of our view model with zero lines of code in code-behind file of our view/page.


For this example I will use Xamari.Forms PCL for Core of the App.

And for hosting simple API for my HTTP GET calls I will use free service called myjson.com it is very nice and handy for tutorials or small testings.

This is how my project structure looks like for now:



In Models folder now I will add simple class "Car" with three properties: CarID, Make and YearofModel.

... and it looks like this:

Now I will add my page called CarsPage inside of Views folder, like this:


As you can see we have very simple page with list view in it, list view has ItemTemplate and DataTemplate in side of it. ListView controls is binding to Items of type ObservableCollection and the data in side of list view will be binding to the properties of the class Car to the two properties Make and YearOfModel. If this is little confusing for you I suggest you to take a look at my early tutorials about bindings and hope that will be helpful for you.

Now when we have this page we need a view model which we will make logic for updating the list data and we need view model in order to follow MVVM rules in our app.

Maybe in future I will make my own blog post about why to use MVVM and for now I suggest you to take a look at this great answers on Stack Overflow. Why use MVVM?

.. Now lets create that view model called CarsViewModel.cs and it looks like this:
If this code is confusing for you I strongly recommend you to take a look at my blog post: Xamarin.Forms Simple MVVM Binding Example

In that blog post I am explaining the INotifyPropertyChanged and OnPropertyChanged in more detail way.

But I will now write couple of word here: INotifyPropertyChanged is interface which this view model class will implement and it have OnPropertyChanged  method which we will be calling on the spots where we are updating the data and OnPropertyChanged method will be changing the value of our controls with zero of code in the code behind classes.

Now when we have this view model (in which we will add couple of lines of code later), we need to connect with our page and we can do that in the CarPage.xaml.cs like this (at line 19.) :



Now we can run our app and hopefully we will have list of two cars displayed. (Also do not forget to set in your App.xaml.cs: main page to be: MainPage = new CarsExample.Views.CarsPage(); or navigate to the CarsPage as you want.)

Here is our app and how CarsPage looks like:



For now this is a result that we want to accomplish, now we want to update automatically the data in the list and that will be very easy using MVVM and OnPropertyChanged Method.

In the Utils folder I will add the class called MyHTTP and this will be my helper class for calling the web service to get data that will be in the list after update. So add that class and it looks something like this:

Maybe this approach will be strange for you but this is a way that I like to use async methods:

If you have any issue with HTTPClient you can solve this by adding Microsoft.Net.Http nuget package in your project PCL.

After this we need to make API Call in the our view model class like this: (from line 47. to 53.)

If everything is OK, now we can run our app, and result need to be that we have our list view with two default values and after couple of seconds (to make api call and deserialize data) we will have updated list with new values. (Do not forget to turn on wi fi on your device.)

I will make a gif demo for this app, so you can see here how it will look like when you run it on your pc and device.

As you can see on the gif down bellow there is a list of default values after couple of seconds list is updated and all that from our view model with minimum of lines of code at the code-behind.

Demo (gif):




As always demo code will be on the my GitHub, here at almirvuk/Xamarin.Forms_MVVM_ListView_Binding.Example


Hope that this tutorial was helpful for you in your process of development or learning Xamarin.Forms, if it is share it with your colleagues and good luck with development.

Best regards! Almir Vuk https://almirvuk.blogspot.com/

You Might Also Like

21 comments

  1. Almir, thanks for spending the time doing this. Nice tutorial.

    ReplyDelete
    Replies
    1. Thank you for the comment I am glad that this blog post was helpful for you!

      Delete
  2. powerful Tutorial,Thanks alot...i liked your Master-Detail Page Navigation menu in Xamarin.Forms too

    ReplyDelete
  3. Thanks,very nice Tutorial.

    ReplyDelete
  4. Thanks for tutorial, very goof. Reading "https://developer.xamarin.com/guides/xamarin-forms/enterprise-application-patterns/" I very confuse about navigation between ViewModel, so I hope that your next tutorial regard this argument.

    ReplyDelete
  5. love it, but the view model picture isn't loading for me :(

    ReplyDelete
  6. Hello, I am trying your sample and I get this warning from Visual Studio: "Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call".

    It is just a warning, so the code compiles right. But the execution in my case fails. Although the 2 default values show correctly, the 3 values supposed to be retrieved from the API never show in the screen.

    Do you think there could be some deadlock the code is incurring in?

    Thank you in advance and also for the post.

    ReplyDelete
    Replies
    1. Hi,

      Can you post your code snippet from ViewModel, so we can see where the problem is.

      Best regards!

      Delete
  7. Here is my code (almost exactly the same as yours):

    using RestDem.Models;
    using RestDem.Utils;
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Text;
    using System.Threading.Tasks;

    namespace RestDem.ViewModels
    {

    public class CarsViewModel : INotifyPropertyChanged
    {

    private ObservableCollection items;

    public event PropertyChangedEventHandler PropertyChanged;

    public ObservableCollection Items
    {
    get { return items; }
    set
    {

    items = value;
    }
    }


    public CarsViewModel()
    {

    // Here you can have your data form db or something else,
    // some data that you already have to put in the list
    Items = new ObservableCollection() {
    new Car()
    {
    CarID = 1,
    Make = "Tesla Model S",
    YearOfModel = 2015
    },
    new Car()
    {
    CarID = 2,
    Make = "Audi R8",
    YearOfModel = 2012
    },

    };

    // Web service call to update list with new values
    MyHTTP.GetAllNewsAsync(list =>
    {
    foreach (Car item in list)
    Items.Add(item);
    });
    }
    }
    }

    I had to add the "public event Property..." so the code compiled, otherwise it said that CarsViewModel didn't implement interface member INotifyPropertyChanged. So once I added this extra line, the code compiles right, but never shows any entry in the list.

    If, trying another way, I remove the ": INotifyPropertyChanged" from the definition of CarsViewModel (and then don't need the former extra line), the the code compiles right again, show the two default values, but never shows the values to retrieve from the API url.

    Thanks for your attention.

    ReplyDelete
    Replies
    1. Have you tried to debug your app just to be sure that you fetch the data from api?

      Delete
  8. I will thank you. I think somehow the data are not being fetched.

    ReplyDelete
  9. i am trying this but its not working somehow and i am not able to post the code as the comment box does not accept it
    any alternative for me ?

    ReplyDelete
    Replies
    1. You can post the code to gist on github and paste url here :D

      Delete
  10. please its not working... i have tried many times..can you please give more insight

    ReplyDelete
    Replies
    1. Hi,

      What exact problem you have, can you explain it more, did you try to run the code example from github?

      Best regards!

      Delete
  11. Hi again!
    I know it's not about the topic, but I didn't find anything on the Internet, so I would to ask you if it is possible to create a Grouping Enabled ListView without using MVVM? Because I don't want to use MVVM.
    Other question: it's correct to use MVVM structure just in some pages of my app? Like this one with Grouping Enabled?

    Thank you in advance.

    Best regards!

    ReplyDelete
    Replies
    1. Hi Bruno,

      Yes, it is, Grouping in ListView is separate from MVVM.

      https://montemagno.com/enhancing-xamarin-forms-listview-with-grouping/

      Follow this tutorial and don't use ItemsSource Binding to your list in ViewModel, you can set the ItemsSource of your ListView from code-behind class.

      Is that ok?

      Delete
    2. Hi!

      Yes, that tutorial helped me a lot, like your tutorial. And I had discovered too, that I can still use ObservableCollection in my code-behind, puting the ObservableCollection to ItemsSource, and not use View Model. Tested and it worked!

      Thank you.

      Delete
  12. This works great for me on an Android emulator but not on ios (live player). Is anyone else having this issue?

    ReplyDelete