Fork me on GitHub

A Simple Model-View-ViewModel pattern example (Universal Apps Model) [.NET]

Introduction

It took me a few days to get my head around Model-View-ViewModel (MVVM) pattern. I was reading various books as well as following tutorials that I found on internet, but I was still struggling to fully understand how MVVM does it’s magic.

And I think my problem was in me trying to refactor one of my existing apps and make it follow MVVM rules. That introduced me to a lot of unnecessary complications at the time. So I decided to start making a very simple app from scratch and that’s how I finally got the basics at least.

This app doesn’t use custom interfaces, but it shows how to consume a simple Mashape API within MVVM. Although there is much more into MVVM than I’m showing in this app, but I hope it will at least help someone to get started.

Source files on GitHub.

Solution

Views

The code inside the Grid identical for both Windows and Windows Phone apps.

Putting it simply:

  • Instead of using TextChanged event, text boxes are now notified by ViewModel when the text changes and updates accordingly. So they are not attached to any code behind any more and can be removed safely, without breaking whole app, as well as many other controls can be added and reuse same Binding bit, and be updated without adding any extra code behind them.
  • Instead of using Click event, the button now uses Command element and works in similar way as text boxes, and receives same benefits.

I know, the explanation is far from professional, but there are plenty of information on Internet, written in very professional and academic way, about data binding, decoupled architecture, unit testing and how Command Design pattern is used.

<Grid>
    <TextBox HorizontalAlignment="Left" Margin="604,315,0,0" TextWrapping="Wrap" Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" PlaceholderText="Add name..." Width="158"/>
    <TextBox HorizontalAlignment="Left" Margin="604,367,0,0" TextWrapping="Wrap" Text="{Binding Path=Gender}" VerticalAlignment="Top" IsReadOnly="True" Width="158"/>
    <Button Content="Get person's gender" Command="{Binding UpdateGender}" HorizontalAlignment="Left" Margin="601,420,0,0" VerticalAlignment="Top" />
</Grid>

ViewModel

Well, here’s the-man-in-the-middle bit, which allows View and Model to communicate each with other. He’s the one who shouts out loud when something is changing and lets View and Model to know about it and to update accordingly.

Instead of implementing INotifyPropertyChanged and ICommand logic for every ViewModel, it’s much better to move them to their own classes and reuse them when needed as ObservableObject and RelayCommand objects. It’s confusing at the beginning as some different tutorials are using different approaches.

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Input;
using DonatasSimpleUniversal_MVVM_App.MVVMFramework.Models;
using DonatasSimpleUniversal_MVVM_App.MVVMFramework.MVVMHelpers;
using DonatasSimpleUniversal_MVVM_App.Services;
using Windows.Data.Json;

namespace DonatasSimpleUniversal_MVVM_App.MVVMFramework.ViewModels
{
    public class PersonViewModel : ObservableObject
    {
        // Members
        Person _Person;

        // Constructs the default instance of a PersonViewModel
        public PersonViewModel()
        {
            _Person = new Person();
        }

        // Properties
        public Person Person
        {
            get
            {
                return _Person;
            }
            set
            {
                _Person = value;
            }
        }

        public string Name
        {
            get 
            { 
                return Person.Name; 
            }
            set
            {
                if (Person.Name != value)
                {
                    Person.Name = value;
                    RaisePropertyChanged("Name");
                }
            }
        }

        public string Gender
        {
            get
            {
                return Person.Gender;
            }
            set
            {
                if (Person.Gender != value)
                {
                    Person.Gender = value;
                    RaisePropertyChanged("Gender");
                }
            }
        }

        // Commands
        void UpdateGenderExecute()
        {
            MashapeAPI mashapeAPI = new MashapeAPI();
            string json = mashapeAPI.getGenderInformation(Name).Result;

            JsonObject jsonObject = JsonObject.Parse(json);
            Gender = jsonObject.GetNamedString("gender");
        }

        bool CanUpdateGenderExecute()
        {
            return true;
        }

        public ICommand UpdateGender { get { return new RelayCommand(UpdateGenderExecute, CanUpdateGenderExecute); } }
    }
}

Model

The Model(s) is probably the easiest bit to do, and perhaps that could be the starting point when developing a new app, because it allows you to see and plan on what objects you will be working later, as you don’t need to use all the properties defined here in your ViewModel.

I saw Model being merged with ViewModel on some examples on internet.

using System;
using System.ComponentModel;
using System.Text;

namespace DonatasSimpleUniversal_MVVM_App.MVVMFramework.Models
{
    public class Person
    {
        // Members 
        string _Name;
        string _Gender;

        // Properties
        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }

        public string Gender
        {
            get { return _Gender; }
            set { _Gender = value; }
        }
    }
}

Comments !

links

social