James Montemagno
James Montemagno

Live, Love, Bike, and Code.

Live, Love, Bike, and Code

Share


Tags


AsyncCommand & More Come to MVVM Helpers

Having to write boilerplate code over and over again is not only annoying, but it is a time sink when trying to build apps. That is why nearly 4 years ago I created a small little open source library to get rid of MVVM boilerplate code that I called MVVM Helpers. It contains all sorts of goodies including an ObservableObject, BaseViewModel, ObservableRangeCollection, and all sorts of small utlilities. I use it in every app that I have ever built since its original release and it has been downloaded nearly 500,000 times.

What's Next for MVVM Helpers

The library has been moving along pretty nicely, with small enhancements here and there, but I never really planned for much more. Until Holly tweeted at me last week about using lambas in Commands:

This eventually lead me down a path of reading a great blog by John Thiriet on going async with async command. I immediately thought to my self.... Why isn't this in MVVM Helpers?!?!?!? So this weekend I sat down and combined a bunch of code from John, Xamarin.Forms, and Brandon Minnick's AsyncAwaitBestPractices library, and jammed it into MVVM Helpers.

So, I am pleased to introduce MVVM Helpers version 1.5.0 packed full of all sorts of new goodies for developers!

Enter AsyncCommand

Let's first look at Holly's tweet and the code you would normally write with the build in Xamarin.Forms Command.

public ICommand MyCommand { get; }
public MyViewModel()
{
    MyCommand = new Command(async () => await DoAsync());
}

async Task DoAsync()
{
   // do stuff async
}

The issues here is that the code is a bit gross and also handling exceptions is a bit tricky if something goes wrong. Now with AsyncCommand built into MVVM Helpers the code looks like this:

public ICommand MyCommand { get; }
public MyViewModel()
{
    MyCommand = new AsyncCommand(DoAsync);
}

async Task DoAsync()
{
   // do stuff async
}

The nice part here is that you are still creating an ICommand, which will work great with Xamarin.Forms.

The other thing that you can do is pass in a bunch of other parameters to handle exceptions and also if it can execute or not:

public ICommand MyCommand { get; }
public bool canExecute;
public MyViewModel()
{
    MyCommand = new AsyncCommand(DoAsync,
        (t) =>
        {
            return canExecute;
        },
        (ex) =>
        {
            // Handle exception here
        });
}

async Task DoAsync()
{
    // do stuff async
}

There is also AsyncCommand<T> that can be used if you need to pass in a parameter to the method:

public ICommand MyCommand { get; }
public MyViewModel()
{
    MyCommand = new AsyncCommand<string>(DoAsync);
}

async Task DoAsync(string parameter)
{
    // do stuff async
}

Command and WeakEventManager

Additionally, I decided that sometimes you may want to use a Command in your shared code and not have to bring in Xamarin.Forms. This is why I ripped the code directly out of Xamarin.Forms and put it into MVVM Helpers!

public ICommand MyCommand { get; }
public MyViewModel()
{
    MyCommand = new Command<string>(Do);
}

void Do(string parameter)
{
    // do stuff async
}

Finally, there is a new WeakEventManager also pulled out of Xamarin.Forms that handles raising of EventHandlers. The nice thing about using WeakEventManager is that it will allow for garbage collection when an event handler is still subscribed. I made it public so you can also use it if you are creating EventHandlers in your own project.

readonly WeakEventManager weakEventManager = new WeakEventManager();
public event EventHandler CanExecuteChanged
{
    add { weakEventManager.AddEventHandler(value); }
    remove { weakEventManager.RemoveEventHandler(value); }
}

Available Now

You can grab the library on NuGet right now and of course open an issue or send a PR on GitHub.

See it in action

It is fun to look back to when I first started The Xamarin Show and some of the early episodes I did, including one on MVVM Helpers:

Copyright © James Montemagno 2019 All rights reserved. Privacy Policy

View Comments