Author: saraford

Displaying a ListView item from Page1 on Page2 – Part 8 and Final – Writing a Xamarin.Forms app

Just joining the series? Here’s a recap:

Welcome to the grand finale!

Whenever I try to go down the MVVM path, I always get stuck at “How do I get PageOneViewModel and/or Page1.xaml to know about the list of Fabrics?” For example, suppose I want my Page1.xaml to show the Name of the current Fabric and its corresponding seconds. How does Page2 get the Fabric data from Page1? Fortunately, this final blog post answers this question!

Recall how my #1 biggest issue was thinking the ObservableCollection should be the “source of truth” – meaning the app pulls its fabric data requirements from the ObservableCollection (which is wrong and don’t do this). In the past, I’d achieve this by making the ObservableCollection a global variable and other things I’d brute force or SO cut and paste.

But now we have this data service. Since none of my viewmodels are instantiating the data service (my #2 biggest issue blocking me from understanding MVVM), it’s fair game for my other viewmodels to use the data service as well.

To follow along, view this diff from the previous blog post.

I have a question!!!!

  • I’m not sure why I have to specify public Fabric CurrentFabric { get => currentFabric; set => SetProperty(ref currentFabric, value); } I figured the BaseViewModel took care of all things INotifyPropertyChanged related. I also thought Mode=TwoWay would work. My only guess is this is the first time in my app thus far that the code has changed the property and not the user input, so extra stuff is needed that BaseViewModel can’t do.

Getting a Fabric to display in PageTwo

First, let’s add a Fabric property to PageTwoViewModel to databind. We’ll talk about where we get this fabric from in a bit.

public Fabric CurrentFabric { get; private set; }

inside the PageTwoViewModel constructor, let’s grab a Fabric from the data service. Just like last 2 blog posts, let’s write our “object model” first, and then implement it later.

CurrentFabric = FabricsDataService.GetFabric(0);

Next, let’s update the Page2.xaml

        <StackLayout Padding="20" HorizontalOptions="Center">
            <Label Text="{Binding CurrentFabric.Name}" FontSize="20" />
            <Label Text="{Binding CurrentFabric.Seconds}" FontSize="20" />

And in the FabricsDataService, add a GetFabric method

        public static Fabric GetFabric(int id) {
            return Application.Current.Properties[id.ToString()] as Fabric;

And let’s run it.

And what the…. we crash on launch??

Exception throws on launch

Looking at the callstack, it’s when we try to get the first fabric. There is no first fabric on first launch…

Turns out I was wrong in a prior post. For a tabbed control, both tab pages are instantiated at launch and are *not* re-instantiated each time you tab to them.

This means we need a way to handle first launch. In Page2.xaml.cs code-behind, we’ll add a

        protected override void OnAppearing()


and in the PageTwoViewModel, let’s only try to get a fabric if the count is > 0.

        internal void InitializeForFirstRun()
            if (FabricsDataService.GetAllFabrics().Count > 0)
                CurrentFabric = FabricsDataService.GetFabric(0);

Now when you run, after you add a fabric, you’ll see it appear in Page2!!!!

Let’s go one step further.

Let’s add a command to go to the next fabric (provided you’ve added two).

You’ve seen how to add a command in previous posts, so here’s the delegate in PageTwoViewModel.cs

        public void NextFabric() {

            CurrentFabric = FabricsDataService.GetFabric(1);


Like I said, make sure you have at least 2 fabrics in this list! This is just to demo calling out to the FabricsDataService!!!

Now I thought the BaseViewModel would handle all updates made to CurrentFabric if we specified TwoWay binding, but it doesn’t and I’m still not sure why. You still need to add the following to PageTwoViewModel

        private Fabric currentFabric;
        public Fabric CurrentFabric { get => currentFabric; set => SetProperty(ref currentFabric, value); }

Now the CurrentFabric changes will be picked up!

That’s it for this series!

At least for now. My goal was to explain how one page in a tabbed control could get access to another page’s data-bounded items in a ListView, which we now know is the wrong question. The more accurate question is how to use a “DataService” to get access to a ListView from a different tabbed page.

Where I’d like to go next:

  • How might I add unit testing to my app? If you have a link or an example, please let me know! I should be able to test my services and my ViewModels, right?
  • How might dependency inject help me? Is this a requirement for unit testing or do I have enough to add unit tests?


Using App.Properties as source of truth – Part 7 – Writing a Xamarin.Forms App

Continuing from last post, we need that “source of truth” for the real Fabric list that the FabricDataService uses to perform CRUD operations.

To follow along, check out the diff from last post here.

Matt Soucoup has a great write up on using App.Properties in Xamarin.Forms.  App.Properties will be my “source of truth” for my service. I could also use the Settings plugin, but to keep this blog post focused on what the service is doing, I’m going to stick with App.Properties for this blog post.

Note: App.Properties is supposed to persist data across installs (i.e. debugging builds), but I’m running into this issue.  I’ve tried doing await Application.Current.SavePropertiesAsync() but still didn’t persist the fabrics. Moving forward, I’ll switch to the Settings plugin because I don’t want to recreate these fabrics every deploy.

What I learned

  • Oh yeah, every time you tab to a new page or open a new page, that page is being created for the first time. I have no idea why I’m so paranoid about saving memory and thinking I need to keep cached versions of these pages around all the time.
  • The Settings plug is actually quite simple as well, but for this demo, I wanted to use as few lines of code as possible to demonstrate the service, not the underlying save/persistence mechanism.
  • Think of App.Current.Properties as a way of getting the Fabrics from “storage” whether that is from disk (which is what this is doing) or from something else like Settings plugin, or from a cloud service.
  • It’s okay that every time you need to get the list of fabrics, it pulls it from “storage”. I have no idea why I want to cache everything so badly.

In the FabricDataService, we now have for GetAllFabrics()

        public static List<Fabric> GetAllFabrics()

            List<Fabric> fabrics = new List<Fabric>();

            if (Application.Current.Properties.Count == 0)
                return fabrics;

            for (int i = 0; i < Application.Current.Properties.Count; i++)
                var fabric = Application.Current.Properties[i.ToString()] as Fabric;

            return fabrics;

And AddFabric() becomes

        public async static void AddFabric(Fabric fabric) {

            fabric.Id = Application.Current.Properties.Count;
            Application.Current.Properties.Add(fabric.Id.ToString(), fabric);
            await Application.Current.SavePropertiesAsync();

Next, we have to add UpdateFabric() to the data service for when the user edits an item in the ListView.

        public static void UpdateFabric(Fabric fabric)

            Xamarin.Forms.Application.Current.Properties.Add(fabric.Id.ToString(), fabric);

Lastly, have DoneEditing() call the DataService.  

        private async void DoneEditing()
            if (isNew) {


                MessagingCenter.Send<ItemDetailsViewModel, Fabric>(this, "added", this.Fabric);
            } else {



            await Navigation.PopAsync();

Now when you run the app, you’ll notice no obvious change in functionality. You can add fabrics and tab between the two pages just as before which is a good test. One thing I had to remind myself is that every time you open a page (whether navigating between two pages or opening the ItemDetailsPage), you are recreating a new instance of the View and ViewModel.

Sara can has DataService – Part 6 – Writing a Xamarin.Forms app

Just joining my series? Check out my first blog post in this series for an overview on what I’m building.

To follow along, here’s the diff from last blog post.

What I learned

  • The term “service” is a naming convention. There’s no special library you have to install to make a class act as a “service”.
  • Not everything has to be instantiated. Yeah this is the first time I’ve been forced to think this way. You don’t have one of your view models or your main app class instantiate your service. Use either a singleton or a static class.
  • Global variables are not good form. I can’t stop my brain from wanting to do a List somewhere off of the main App as the source of truth. Let the data service handle this. It will make more sense in this blog post and the next post.

Creating a FabricsDataService

First, create a new folder called Services and add a blank C# class there called FabricsDataService

Back in the days where I was a developer (SDET) on the VS team (LONG time ago), I remember the advice I got from a developer reviewing my code. He said, “Think about writing your Object Model from the point of view of the caller. Start by writing your test cases, thinking about what methods you wish were already available, and then go implement those methods.” This conversation might have been my first introduction to HCI / UX. 

Writing a service is kinda like writing that object model ages ago. Start with what methods you wish were available to you, and then go implement them. For example, in PageOneViewModel.cs in the constructor, I’m creating fabric objects just to populate the ObservableCollection.

In GitHub, press y to get a permalink to a specific commit; otherwise, if you use master and it gets updated, your link might not make sense moving forward.

For example, I’m doing

        public PageOneViewModel(INavigation Navigation)

            OCFabrics = new ObservableCollection<Fabric>();

            OCFabrics.Add(new Fabric("fabric1", 5));
            OCFabrics.Add(new Fabric("fabric2", 5));
            OCFabrics.Add(new Fabric("fabric3", 5));

but my ViewModel doesn’t care what the Fabrics are or where they come from (memory, disk, the cloud?). It just wants to get all the fabrics.

You can rewrite this as

var allFabrics = FabricsDataService.GetAllFabrics();

The MVVMHelpers also has an ObservableRangeCollection that gives you extra methods like ​AddRange() since ObservableCollection only has Add() so you end up writing less code.

Now we can do

var allFabrics = FabricsDataService.GetAllFabrics();

Now all we have to do is implement GetAllFabrics().

Introducing my biggest mental hurdle to MVVM

Okay here’s my biggest mental hurdle… what is FabricsDataService? I mean what sort of class is this? Where do I “new it up” or instantiate it? Turns out you’d either want to use a singleton class design pattern or just a static class. Since I’m learning to crawl towards MVVM, I’m going with static class since it is the easiest for me to conceptualize.

My next question is “where is this list of Fabrics stored in memory for other parts of my app to use?” Turns out it isn’t stored anywhere per-se. When my Page2 needs it, that page will simply called the data service. It seems redundant to me to keep new’ing up a List of fabrics on demand, especially if those are coming from disk or a web service. But I’ve had several people advise me to get past this idea that I need an app-wide List as the source of truth and instead rely on a (Fabric)DataService. I guess it’s the difference between fast food (my app-wide List vs “made to order” DataService. But then again, I remember being told all throughout my professional development days global variables are bad… so hello FabricDataService!

First, make FabricDataService a static class

public static class FabricDataService

and remove the default constructor (since it’s static).

Now back to our GetAllFabrics()… where do we get the data from? Since this is just about using the FabricDataService, we’re going to just new up those 3 fabric objects, e.g.

public static List<Fabric> GetAllFabrics()

            List<Fabric> fabrics = new List<Fabric>();

            fabrics.Add(new Fabric("fabric1", 5));
            fabrics.Add(new Fabric("fabric2", 5));
            fabrics.Add(new Fabric("fabric3", 5));

            return fabrics;

And now let’s rock on and hit Run (or whatever F5 translates to a Mac). And we get…

Fabrics displayed in ListView coming from DataService

Boom goes the dynamite!

But what about adding? Since we’re using ItemDetailsPage for both editing and adding, we have to check whether we’re editing a new item and respond accordingly. For example, in ItemDetailsViewModel,

        private async void DoneEditing()
            if (isNew) {


                MessagingCenter.Send<ItemDetailsViewModel, Fabric>(this, "added", this.Fabric);
            } else {



            await Navigation.PopAsync();

Which now begs the question… what is the FabricDataService updating? We already said we didn’t want to use some app-wide global List as our source of truth. So what is the source of truth for the DataService????

This question is also known as my #2 biggest hurdle learning MVVM, which I’ll address in my next blog post: Application.Current.Properties versus Settings plugin.

Adding items in a List View – Part 5 – Writing a Xamarin.Forms app


Last blog post discussed editing items. This blog post uses the MessagingService in Xamarin.Forms to tell the ObservableCollection to add a new item.

To follow along, here’s the diff for this post.

What I learned

  • It’s okay to use the MessagingCenter even in a MVVM pattern. At first I didn’t think this was correct, even though the MessagingCenter appears in the Xamarin documentation under MVVM for adding a new item on a ListView. Obviously I have trust issues.
  • The observable collection updates when its .Add() is called.

Add a footer in the Page1.xaml for the Add button

                        <Button Text="Add Fabric" FontSize="Large" Command="{Binding AddFabricCommand}" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" />

Then in the PageOneViewModel, add the command property

public ICommand AddFabricCommand { get; private set; }

and in the constructor, create a command to bind to.

AddFabricCommand = new Command(AddFabric);

and now finish up with the delegate

        private async void AddFabric()

            Fabric fabric = null;
            await this.Navigation.PushAsync(new ItemDetailsPage(fabric));

Now we need to update the ItemDetailsViewModel constructor to handle a new fabric, i.e. if a fabric passed in is null

first we need a property to know if we’re adding  a new fabric or editing an older one.

private bool isNew = false;

now for the constructor

public ItemDetailsViewModel(INavigation Navigation, Fabric fabric)
            isNew = fabric == null;

            if (isNew)
                this.Fabric = new Fabric(Name: "", Seconds: 60);
                Title = "Hello from new item";
                this.Fabric = fabric;
                Title = "Hello from Item " + Fabric.Name;

            this.Navigation = Navigation;
            DoneEditingCommand = new Command(DoneEditing);

Now run the app. You’ll see the familiar ItemDetailsPage appear for the Add, but nothing changes in the ListView. What’s going on?

where's fabric 4

This is because the OCFabric.Add() is never called, so the ObservableCollection can’t add the new Fabric.

Where MessagingService steps in…

When we’re done editing, we need to know whether this is a new fabric or editing an older one so the ObservableCollection can add it.

        private async void DoneEditing()
            if (isNew) {
                MessagingCenter.Send<ItemDetailsViewModel, Fabric>(this, "added", this.Fabric);

            await Navigation.PopAsync();

and now for the receiver. We’re going to subscribe to the message in the PageOneViewModel constructor.

            MessagingCenter.Subscribe<ItemDetailsViewModel, Fabric>(this, "added", (sender, arg) =>

and now Fabric4 is added to the ListView


Note: yeah I know there’s a more “pure” way to use the MessageCenter by creating a class called FabricSaveMessage as the sender, but it hasn’t really clicked yet why I’d want to create another class. Perhaps further on as I develop this app I’ll run into a good reason for not using the ViewModels as the sender and receiver for these messages.

Alrighty! Next blog post begins my real lightbulb moments using MVVM – how to use a “service” to handle being the “source of truth” for the fabric list.

Editing Items in ItemDetailsPage – Part 4 – Writing a Xamarin.Forms app

From the previous blog post, we now have these ListView items, we need to edit them. Persisting this data will be for an upcoming blog post. I’m trying hard not to blog dissertations. 🙂

To follow along, go to my ListViewInTabbedControl and  `git checkout tags/editing-fabrics` or view the diff.

What I learned

  • I do not need to use any TextChanged event because of data binding. I thought you might need to because the ObservableCollection wasn’t updating, but updating individual items is beyond the scope of what ObservableCollection can do. Because our Model.Fabrics derives from ObservableObject which implements INotifyPropertyChange, we’re all good to go! MVVM Frameworks FTW!

Add a Fabric property to the ItemDetailsViewModel

You’ll need a fabric object to create in ItemDetailsViewModel to bind to. In the ItemDetailsViewModel, create a public Fabric property

public Fabric Fabric { get; private set; }

and it in the ItemDetailsViewModel constructor, assign the incoming Fabric object to the Fabric property.

this.Fabric = Fabric;

And that’s it for the view model! Remember, you’re deriving from BaseViewModel, which derives from ObservableObject, which implements INotifyPropertyChange.

Add the textboxes to the View

In Page1.xaml, add the Label and Entry (Xamarin-speak for textbook)

                <StackLayout Spacing="10" Margin="10,30,0,0">
                    <Label Text="Name" FontAttributes="Bold" />
                    <Entry Text="{Binding Fabric.Name, Mode=TwoWay}"                            Keyboard="Text"                            Placeholder="Name of fabric">

                    <Label Text="Seconds" FontAttributes="Bold" />
                    <Entry Keyboard="Numeric"                             Text="{Binding Fabric.Seconds, Mode=TwoWay}"                             Placeholder="Number of seconds (e.g. 60)">
            <Button x:Name="DoneButton" Text="Done" FontSize="Large" Command="{Binding DoneEditingCommand}" HorizontalOptions="Center" VerticalOptions="End"/>

Now you’ll have an edit page for your fabrics


and now your fabrics are edited!


In the next post, I’ll talk about adding a new fabric to the list (including the messaging service). Stay tuned!

Displaying an ItemDetailsPage for a ListView item – Part 3 – Writing a Xamarin.Forms App

My adventures in “I can has MVVM” continues! Please see Part 1 (what this app is) and Part 2 (ListView).

If I’ve misunderstood something, please let me know! The only way to combat Impostor Syndrome is to fight it head on.

To follow along, go to my ListViewInTabbedControl and  `git checkout tags/ItemDetailsPage` or view creating the ItemDetailsPage here and view the adding the commanding diff here.

What I learned

  • There’s an excellent pluralsight course on async and await called Getting Started with Async Programming in .NET
  • Difference between PushAsync and PushModalAsync
  • Why do someFabric as Fabric instead of (Fabric) someItem as seen in this diff? If you use (Fabric), it’ll throw an exception immediately if cast fails, but if you do “as fabric”, it’ll just set to null so you can do things with it. You could always do a try catch if you use (Fabric), but it’s less code to write / cleaner

If you can eventually debug your issue, debugging is a great teacher! 🙂

While writing this post, I found a bug from Blog Post 1.

Originally I was going to refer to a scene from 13 Assassins (2011). Wait, hear me out 🙂 I was thinking of that scene towards the end of the movie where the guy gets hit and experiences pain for the first time, and the other guy says something like “well, that was unexpected.” For some reason, debugging this issue made me think of that scene /shrugs 🙂

When I tried to open the ItemDetailsPage, I got


Say the classic words with me, “But how is this working on my other app?” I know this code below should work to show the I​temDetailsPage

await this.Navigation.PushAsync(new ItemDetailsPage(tappedFabric));

So I tried to give it a NavigationPage…

await this.Navigation.PushAsync(new NavigationPage(new ItemDetailsPage(tappedFabric)))

and I got the same PushAsync is not supported globally on iOS, please use a NavigationPage exception. Grr.

Finally I realized which “Page” the exception was referring to. It’s not referring to the page I was trying to pass it. It’s referring to the page that’s the caller for this.Navigation.PushAsync 

What I mean is in App.xaml.cs, although I created navigation pages for these pages,

var page1Nav = new NavigationPage(page1);
var page2Nav = new NavigationPage(page2);

I neglected to add them to the tabbed control. Notice below I added page1 and page2 and not page1Nav and page2Nav, hence the exception.

var tabbed = new TabbedPage();
tabbed.Children.Add(page1);  // whoops! not a navigation page
tabbed.Children.Add(page2);  // whoops! not a navigation page

Make sure to change these lines to


Okay now back to your originally scheduled blog post, already in progress…

1) User taps an item to be edited in its own page

We’ll use `ItemTapped=”Handle_ItemTapped”` here in the code behind, since there’s not a corresponding bindable property, as you see in SelectedItem.

But what does “not a bindable property” mean? You might be tempted to try “ItemTapped="{Binding ItemTapped}" but that won’t work. You’ll get

Specific Cast Not Valid complier error message

You’ll need to use a click event handler in the code behind for item tapped. Why not just use ItemSelected? Well, the issue is when the user wants to edit the same item twice in a row. For example, say the user edits Fabric 1. Upon returning, this item will still be selected. Although it’s in an “inactive selection” state, you can’t select it again, meaning the user will try to tap it, but nothing will happen. The app will still just look at you. Hence for this UX design requirement, you need to use ItemTapped. And IMO, “tapped” is more descriptive of the action the user is performing than “selecting”.

Add the following code to Page1.xaml

ItemTapped="{Binding ItemTapped}

The ListView now gets its content from the ObservableCollection of Fabrics. I called this OCFabrics to break my reliance on it for all the app’s needs.

And in the codebehind for Page1.xaml.cs, add the following:

async void Handle_ItemTapped(object sender, Xamarin.Forms.ItemTappedEventArgs e){
   Fabric tappedFabric = e.Item as Fabric;

   if (tappedFabric == null)

   await this.Navigation.PushModalAsync(new ItemDetailsPage(tappedFabric));

I’ll go over the significance of PushAsync vs PushModalAsync at the bottom of this post.

2) Create the ItemDetailsPage() – what the user will see when he/she taps on an item

Add a new View called `ItemDetailsPage` under Views. (This is a Forms – ContentPage Xaml in VS for Mac). And a code behind called ItemDetailsViewModel.

Use the following code for the ItemDetailsPage

<ContentPage xmlns=""
Title="{Binding Title}">
            <Label Text="{Binding Title}"
HorizontalOptions="CenterAndExpand" />

and for the codebehind

public ItemDetailsPage(Fabric fabric) {

  var itemDetailsViewModel = new ItemDetailsViewModel(this.Navigation, fabric);
  this.BindingContext = itemDetailsViewModel;

Run this and now you’ll get

displaying Fabric1 when tapped in its own page


3) Now we need a way to escape by adding a Done button and a DoneEditing command.

In the ItemsDetailsViewModel, add a new property for the command

 public ICommand DoneEditingCommand { get; private set; }

in the ItemsDetailsViewModel constructor, create the new command, as shown below

public ItemDetailsViewModel(INavigation Navigation, Fabric fabric) {
            Title = "Hello from Item " + fabric.Name;
            this.Navigation = Navigation;
            DoneEditingCommand = new Command(DoneEditing);

where the `DoneEditing` is the delegate. Add the DoneEditing method in the ItemsDetailsViewModel class, e.g.

        private async void DoneEditing() {
            await Navigation.PopModalAsync();

in the ItemDetailsPage, add a button to your StackLayout

<Button x:Name="DoneButton" Text="Done" FontSize="Large"
Command="{Binding DoneEditingCommand}"
HorizontalOptions="Center" VerticalOptions="End"/>

and voila! You can now hit done and skip around! The item tapped will be shown in the Details Page, e.g. Fabric3 will say “Hello from Fabric 3” with a Done button at the bottom.

Fabric 3 displayed in its ItemDetailPage

Why PushAsync instead of PushModalAsync?

It depends what you’re trying to achieve UX-wise. Do you want the ItemDetailsPage to slide in from the bottom or from the right? Do you want a “back” button in the header on iOS? Do you want a title?

Not sure? Let’s experiment!

The code above is sliding in from the bottom as a Modal pop-up. For sliding in from the right with a back button and a title, you’ll just do

In Handle_ItemTapped() do

await this.Navigation.PushAsync(new ItemDetailsPage(tappedFabric));

and have DoneEditing() to a corresponding

await Navigation.PopAsync();

both the `< Page 1` back button and the Done slide back.


MO this feels like a better UX.

BTW, that back button comes from using NavigationPages as the children of the Tabbed control, as mentioned at the top of my post

But let’s try out the PushModalAsync() to be certain which UX experience we want. Change both Handle_ItemTapped() and DoneEditing() to use Modal. Remember: if you push Modal you need to Pop Modal.

Notice how the Page appears from the bottom, but also no title or back button.


next blog post will talk about editing the items.

Databinding a ListView – Part 2 – Writing a Xamarin.Forms App

Start here: Part 1 – Sara can has MVVM for what I’m building in this series.

Note: Matt Soucoup has been awesome helping me break my mental barrier to using services in a MVVM design pattern. Go check out his Xamarin blog. Consider my blog posts my homework assignments. The only way I truly grok a concept is when I can explain it to someone else.

To follow along, go to my ListViewInTabbedControl and  `git checkout tags/listview-created` or view the diff here.

What I learned

  • Do *NOT* use the ListView’s ObservableCollection as the “source of truth” for a list of fabrics. Forget about the ObservableCollection. It is only for the PageOneViewModel – this is the heart of the issue I have in my head. The source of truth for “What is my official list of Fabrics to iterate through on the other Tabbed page?” comes from a FabricDataService, which I’ll discuss later in this series.
  • Alt+Enter is the Ctrl+. for VS on Mac

1) Add a Fabric Model that derives from ObservableObject

ObservableObject is needed so that when the user edits items, the ListView will get those updates. For example,

    public class Fabric : ObservableObject
        private string name;
        private int seconds;

        public Fabric(string Name, int Seconds)
            this.Name = Name;
            this.Seconds = Seconds;

        public string Name { get => name; set => SetProperty(ref name, value); }

        public int Seconds { get => seconds; set => SetProperty(ref seconds, value); }

        public override string ToString()
            return this.Name + " " + this.Seconds;

2) In PageOneViewModel create an observable collection

For example,

public ObservableCollection OCFabrics { get; set; }

 Note to self: This ObservableCollection is *only* for the View to display items in the ListView. It’s “transient” to the ListView. Do *NOT* use this as the “source of truth” for fabrics, i.e. do not use as the official list of fabrics the rest of the app should use, e.g. which fabric are we on? what’s the seconds remaining for the current fabrics? This has been my biggest mental hurdle in MVVM.

If this isn’t the source of truth, what is? Enter a FabricDataService! More on this in my upcoming blog posts.

Let’s initialize this ObservableCollection with some data. we’ll change where this data comes from in a couple of blog posts using a FabricDataService. We just want a working list view for now.

public PageOneViewModel(INavigation Navigation) {

   OCFabrics = new ObservableCollection<Fabric>();

   OCFabrics.Add(new Fabric("fabric1", 5));
   OCFabrics.Add(new Fabric("fabric2", 5));
   OCFabrics.Add(new Fabric("fabric3", 5));

   Title = "Page One from VM";
   this.Navigation = Navigation;

3) In PageOneViewModel create a ListView.

Note the ItemsSource, SelectedItem, Binding Name, and Binding Seconds.

<ListView ItemsSource="{Binding OCFabrics}"
SelectedItem="{Binding SelectedItem, Mode=OneWay}"
                        <ViewCell Height="60">
                            <StackLayout Orientation="Horizontal">
                                <BoxView BackgroundColor="Blue" WidthRequest="10" Margin="0,0,0,10" />
                                <StackLayout BackgroundColor="White" Orientation="Vertical" Margin="5,5,10,5">
                                    <Label Text="{Binding Name}" FontAttributes="Bold" />
                                    <Label Text="{Binding Seconds, StringFormat='Seconds: {0}'}" TextColor="Gray" />

And give it a run!

App showing the ListView populated with the items added to ObservableCollection

Yay! I can has ListView with data binding!

Let’s call it here for Part 2… Onward to Part 3 – Displaying Items in a ItemDetailsPage (coming soon!)