Model-View-ViewModel (MVVM) Patterns and Practices Cheat Sheet

I’m a creature of habit. I like my projects in MVVM and I tend to set them up a very particular way. If you’ve worked with the MVVM pattern before, you probably have your own methodologies, but if you’re new to the pattern (here’s a quick primer from Microsoft), here are some general rules I try to follow that can get you started. This proposal assumes you are using MVVMLight (which is perhaps the most ubiquitous) , but the general principles apply to similar frameworks, such as Prism and Xamvvm.

Naming Conventions

Views and their related ViewModels should be clearly identifiable for name.

  • For Views: {SomeDescriptor}Page
  • For ViewModels: {NameOfCorrespondingView}ViewModel

For example:

  • Views Folder
    • OrderPage.xaml
    • OrderPage.xaml.cs
  • ViewModels Folder
    • OrderPageViewModel.cs

Making a New Page Using End-To-End MVVM

Here’s a high-level overview on getting a new page set up and ready for MVVM. This section assumes you have already configured your Dependency Injection, have implemented INavigationService, and have already established your navigation page.

  • Create a new View in the Views folder
  • Create a new ViewModel in the ViewModels folder
  • In the constructor of the ViewModel, inherit from ViewModelBase
    public class HomeDashboardViewModel : ViewModelBase
    {
        /*
         * Define Fields
         */
        // TODO:

        /*
         * Define Properties
         */
        // TODO:

        /*
         * Define Commands
         */
        // TODO:

        public HomeDashboardViewModel(INavigationService navigationService)
        {
            this.Title = "Home";
        }

        /*
         * Define Methods
         */
        // TODO:
    }

Notice that we need to provide the INavigationService (discussed later) to the constructor, which will be resolved by our DI container.

  • Register the ViewModel in IoCConfig.cs
        /// <summary>
        /// Registers the view models.
        /// </summary>

        public void RegisterViewModels()
        {
            SimpleIoc.Default.Register<OrderPageViewModel>();
            SimpleIoc.Default.Register<HomeDashboardViewModel>();

            // TODO INIT: Register new ViewModels here
        }
  • Register the ViewModel in ViewModelLocator.cs
        /*
         * Define ViewModels
         */
        public OrderPageViewModel OrderView => ServiceLocator.Current.GetInstance&lt;OrderPageViewModel&gt;();
        public HomeDashboardViewModel HomeDashboardView => ServiceLocator.Current.GetInstance&lt;HomeDashboardViewModel&gt;();

        // TODO INIT: Add new ViewModels Here
  • Register the view Nacvigation in IoCConfig.cs
        /// <summary>
        /// Handles navigation wire up
        /// </summary>

        public void RegisterNavigation()
        {
            var navigationService = new NavigationService();
            navigationService.Configure(nameof(Views.HomeDashboardPage), typeof(Views.HomeDashboard));
            navigationService.Configure(nameof(Views.OrderPage), typeof(Views.BulletinBoardNewItem));

            // TODO INIT: Register new View here

            SimpleIoc.Default.Register<INavigationService>(() => navigationService);
        }
  • Define your ViewModel in the View
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
  xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
  x:Class="MyMvvmApp"
  BindingContext="{Binding Source={StaticResource Locator}, Path=OrderView}"
  Title="Order Page">

From here, you’re ready to start using the MVVM pattern with MVVMLight!

Navigating To and From Your Page

            // Forward
            this._navigationService.NavigateTo(nameof(Views.HomeDashboardPage));
            // Forward with parameters
            this._navigationService.NavigateTo(nameof(Views.OrderPage), parameters);
            // Back
            this._navigationService.GoBack();

Binding ViewModel Properties in the View

Static properties can be added to the View do display a single value that never changes after the ViewModel is initialized:

<Label Text="{Binding Message}" Style="{StaticResource labelSubheading}">

Or, we can create a new property as observable, so that the View is updated anytime the value in the ViewModel changes. This can be very useful in many cases, like when wanting to show a loading indicator:

        /*
         * Define Properties
         */
        private bool _isLoading;
        public bool IsLoading
        {
            get
            {
                return _isLoading;
            }
            set
            {
                Set(() => IsLoading, ref _isLoading, value);
            }
        }

The binding on the View looks the same, but will always reflect the current state of IsLoading

<ListView IsRefreshing="{Binding IsLoading}">

Binding Commands in the View

Commands in MVVM Light are created using a RelayCommand, which is an observable implementation of ICommand. RelayCommands can be constructed with an optional “Can Execute” property, which define when the command can or cannot run. Create a new command in your ViewModel like so:

        /*
         * Define Commands
         */
        public RelayCommand<ClassifiedAdTransferObject> SelectItemCommand { get; set; }
        public RelayCommand AddItemCommand { get; set; }

        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>

        public BulletinBoardViewModel(INavigationService nav, IClassifiedAdService ClassifiedAdService) : base(nav)
        {
            _ClassifiedAdService = ClassifiedAdService;

            SelectItemCommand = new RelayCommand<ClassifiedAdTransferObject>((s) => SelectItem(s));
            AddItemCommand = new RelayCommand( () => AddItem());

            Initialize();
        }

        /*
         * Define Methods
         */
        private void AddItem()
        {
            var pageName = nameof(Views.BulletinBoardPage);
            _navigationService.NavigateTo(pageName);
        }

        private void SelectItem(ClassifiedAdTransferObject item)
        {
            // TODO: handle a click action and use the item parameter
        }

This can then be bound to any element in the view that expects a command and (optional) command Parameter:

<Button Command="{Binding AddItemCommand}" Text="Show me a new page to add items">

With that, you’re ready to start developing with MVVM!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s