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
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/
21 comments
Almir, thanks for spending the time doing this. Nice tutorial.
ReplyDeleteThank you for the comment I am glad that this blog post was helpful for you!
Deletepowerful Tutorial,Thanks alot...i liked your Master-Detail Page Navigation menu in Xamarin.Forms too
ReplyDeleteThanks,very nice Tutorial.
ReplyDeleteThanks 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.
ReplyDeleteYou mean, "very good"... or?
Deletelove it, but the view model picture isn't loading for me :(
ReplyDeleteHello, 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".
ReplyDeleteIt 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.
Hi,
DeleteCan you post your code snippet from ViewModel, so we can see where the problem is.
Best regards!
Here is my code (almost exactly the same as yours):
ReplyDeleteusing 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.
Have you tried to debug your app just to be sure that you fetch the data from api?
DeleteI will thank you. I think somehow the data are not being fetched.
ReplyDeletei 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
ReplyDeleteany alternative for me ?
You can post the code to gist on github and paste url here :D
Deleteplease its not working... i have tried many times..can you please give more insight
ReplyDeleteHi,
DeleteWhat exact problem you have, can you explain it more, did you try to run the code example from github?
Best regards!
Hi again!
ReplyDeleteI 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!
Hi Bruno,
DeleteYes, 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?
Hi!
DeleteYes, 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.
Nice to hear that! :)
DeleteThis works great for me on an Android emulator but not on ios (live player). Is anyone else having this issue?
ReplyDelete