Category Archives: MVVM

MVVM Cross Upgrade to 4.2.2

Coming back to MVVMCross and trying to create a new project, I found that some of the documentation available for the new version (4.2.2 at the time of writing this) is no longer correct; for example, the ToDo file in the sample projects still looks like this:

The steps to get this Store UI working are:

1. Add a reference to your Core PCL project
2. Change App.Xaml.cs so that it creates a ‘new Setup(RootFrame)’ during its OnLaunched:

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
var rootFrame = Window.Current.Content as Frame;

// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();

if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}

// Place the frame in the current Window
Window.Current.Content = rootFrame;
}

if (rootFrame.Content == null)
{
// When the navigation stack isn’t restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter

var setup = new Setup(rootFrame);
setup.Initialize();

var start = MvvmCross.Core.Mvx.Resolve();
start.Start();
}
// Ensure the current window is active
Window.Current.Activate();
}

3. For Windows 8 – Add a views folder and a view – xaml.cs and .xaml based on BasicPage – this
will add 5 files to the Common folder.
– Change the Common/LayoutAwarePage.cs inheritance to MvvmCross.WindowsStore.Views.MvxStorePage
– Change the Common/LayoutAwarePage.cs – remove the OnNavigatedTo and OnNavigatedFrom handlers
– Add some content for your Xaml – e.g.

5. For Windows 8.1 – Add a views folder and a view based on the BasicPage template
– In the .xaml.cs – remove public NavigationHelper NavigationHelper and all referencing code
– In the .xaml.cs – remove the OnNavigatedTo and OnNavigatedFrom handlers
– Add some content for your Xaml – e.g.

This document was very useful. I was looking specifically at the Babel project in the above sample; this won’t compile under MvvmCross 4.2.2. I’ve listed here everything I needed to do to make it.

Mvx has now been replaced with MvxSimpleIoCContainer.Instance

In App.xaml.cs:

var start = MvxSimpleIoCContainer.Instance.Resolve<IMvxAppStart>();

Is now:

var start = MvxSimpleIoCContainer.Instance.Resolve<IMvxAppStart>();
start.Start();

In App.cs:

        private void InitializeText()
        {
            var builder = new TextProviderBuilder();
            Mvx.RegisterSingleton<IMvxTextProviderBuilder>(builder);
            Mvx.RegisterSingleton<IMvxTextProvider>(builder.TextProvider);
        }

Is now is a separate plug-in by the looks of things:

mvvmcrossupgrade

The new code is:

        private void InitializeText()
        {            
            var builder = new TextProviderBuilder();
            MvxSimpleIoCContainer.Instance.RegisterSingleton<IMvxTextProviderBuilder>(builder);
            MvxSimpleIoCContainer.Instance.RegisterSingleton<IMvxTextProvider>(builder.TextProvider);
        }

MVVM Cross – Stubbing out IMvxMainThreadDispatcher with RhinoMocks

This article describes how to stub out the IMvxMainThreadDispatcher, used by MVVM Cross, using Rhino Mocks.

Here is an excellent article on unit testing in MVVM Cross.

In it, Stuart Lodge describes a manual mock to replace the `IMvxMainThreadDispatcher`. I’ve recently started using RhinoMocks again, and the following is basically the manual mock described in the above article, in RhinoMocks:

var mainThreadDispatcher = MockRepository.GenerateMock<IMvxMainThreadDispatcher>();
mainThreadDispatcher.Stub(x => x.RequestMainThreadAction(Arg<Action>.Is.Anything)).WhenCalled(a => ((Action)a.Arguments.First())()).Return(true);
Mvx.RegisterSingleton<IMvxMainThreadDispatcher>(mainThreadDispatcher);            

As with many of my posts, this is predominantly for my own use; and, as with those other posts, I hope you’ll find this useful.

MVVM Cross – Creating a New Plug-in

This is quite a straightforward process, and well documented in several places – including here and here; and the sample that I used to create mine (and this tutorial) is here. However, I couldn’t find a step-by-step tutorial in a single place. So this is pretty much for my future self.

Disclaimer(s)

This only applies to Windows Store and Windows Phone. Although I believe the same process applies to iOS and Android.

The plug-in that I’m creating here will create a secondary tile on Windows Phone / Windows Store. However, this only covers the phone part, and doesn’t actually cover tile creation.

Create a Project

The project that I’m dealing with is a re-write of this application, using C# and MVVM Cross.

Obviously, your structure may be different, but the important thing is the Plugins folder at this stage; create a new portable project.

plugin1

Next, add the MVVMCross libraries:

plugin2

Interface and Plugin Loader

The portable class library above needs two files. Start with creating an interface:

    public interface ITile
    {
        Task<bool> CreateTile(string title);
    }

And next, the plug-in loader:

    public class PluginLoader : IMvxPluginLoader
    {
        public static readonly PluginLoader Instance = new PluginLoader();

        public void EnsureLoaded()
        {
            var manager = Mvx.Resolve<IMvxPluginManager>();
            manager.EnsurePlatformAdaptionLoaded<PluginLoader>();
        }
    }
}

Obviously, the next stage depends on your specific implementation. Mine depends entirely on the platform, so that’s all I need to do in the portable library.

Windows Phone

Create a new library project:

plugin3

plugin4

As before, you need to add the MVVM Cross Libraries, and a reference to the portable class above:

plugin5

The next stage is to implement your plug-in logic for the destination platform; in my case, this is logic to add a tile to Windows Phone:

    public class TilePlugin : ITile
    {
        public async Task<bool> CreateTile(string title)
        {
            // Create Tile code
        }
    }

Finally, just implement IMvxPlugin like this:

    public class Plugin : IMvxPlugin
    {
        public void Load()
        {
            Mvx.RegisterSingleton<ITile>(new TilePlugin());
        }
    }

Using the plug-in – the View Model

So, to all intents and purposes, the plug-in is now written (admittedly it only exists for Windows Phone, but that’s beside the point).

Next, it needs to be used; the first thing is to reference it.

plugin6

Here’s my logic to actually use the plug-in inside the view model:

    class SetupNewMailViewModel : BaseViewModel
    {
	. . . 
	
	        private void AddTile()
	        {
	            var tile = Mvx.Resolve<ITile>();
	            tile.CreateTile(MailHeading);
	        }
	    }
	

Using the plugin – Platform Specific

In the relevant project, a reference is needed:

plugin7

The only thing left to do for the platform is to add the bootstrap code:

public class TilePluginBootstrap : MvxPluginBootstrapAction<Tile.Plugin.PluginLoader> {    }

`MvxPluginBootstrapAction` signifies that the call to `MvxSetup` will call the BootstrapRunner for this plugin. Or, to put it another way, this magically makes MVVMCross aware of your new plugin for each platform.

Notes on Deployment

Above, I’ve basically manually added the reference to the correct project. This works fine when I’m working locally, but for an actual distributed plug-in, it’s NuGet that handles this.

Creating a Shared Project in WPF

The new thing for VS 2013 is Universal Apps. They allow you to create a Win 8 and Phone app with shared code. But what if you’re writing LOB apps in WPF, maybe using MVVM? You may have a Winforms app and a XAML app, and want to share code; or have two WPF apps that share a core code base, and some screens.

This post walks through creating a sample shared app.

Create WPF App

I’ll just cover WPF in this post. Start by creating a new application:

sharedcode1

Okay, so we have a WPF application (as you might already have). How to create a shared project? Well, the bad news is: you can’t; at least as far as I’m aware (please, please, please let me know in the comments if you know this to be false!).

So, if you can’t create a shared application without a universal one then create a universal one in the same solution:

sharedcode2

This creates a shared app with a reference from Windows 8.1 and Windows Phone 8.1:

sharedcode3

Now, what comes next might feel like a hack… and there’s a good reason for that!

Have a look in the Win 8 app csproj:

sharedcode4

Copy this into the csproj file of the WPF project (remember the path may be different – although in this case, are not):

sharedcode6

The important thing here is the `Label`. However, you’re most likely to get the path wrong. If you do then when you update the project in VS it will fail to load and give you an error message telling you where it’s trying to find the shared project. Having done this a couple of times, my advice is have this error message up, and try to navigate to the path in Windows Explorer: you should see where you went wrong quickly enough.

Adding stuff to the shared project

Start by adding a page to the shared project so that we can see that it works:

sharedcode7

Make it obvious so that you can recognise it:

sharedcode8

Okay, so you’ve now created a shared project, added some shared content, and referenced it from your main project. Next, tidy up by removing Windows 8 and Phone 8 apps and add a second WPF app:

sharedcode9

To make sure that this is, in fact, a shared project, create and make the same change to the second project and then modify each to call the shared page; e.g.:

    private void Button_Click(object sender, RoutedEventArgs e)
        {
            TestPage test = new TestPage();
            Window w = new Window();
            w.Content = test;
            w.Show();

        }

Then run both projects:

sharedcode10

Notes, and using this in an MVVM architecture

Okay – some things that are worth noting here. The main thing is this: the shared code is just that – shared. If you call something like:

typeof(TestPage).Assembly

You will get the assembly of the running application. Effectively, you’ve created a kind of link between the projects, without the messiness of actually creating a link. The consequences of this are that you must ensure that code in the shared project only has dependencies that can be resolved in ALL the projects that include the shared project.

MVVMCross

I’ve tried this on MVVM Cross using two projects and sharing XAML files; and it works. MVVM Cross looks in the current assembly for a `MyView`, when you navigate to a `MyViewModel`. It will find it providing all your projects reference the shared project and you do not try to re-implement the view.

To clarify:

– Creating a shared project between Winforms and WPF that shares a XAML file will most probably not work (admittedly I haven’t tried it).

– Creating a shared project for two WPF projects and copying MyView.xaml into the shared project, leaving the original intact will cause MVVM Cross to fail to resolve the page (because it doesn’t know which one you want).

Automatically focus on the newest item in a ListView using WinRT, MVVM and Behaviors SDK

The Behaviors SDK was introduced recently for WinRT. Here’s how you could use it to add functionality to a Listview to scroll to the newest item.

ListView

To start with, here’s the listview XAML:

            <ListView ItemsSource="{Binding DataLog}" x:Name="StatusUpdate">                
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding}" />
                    </DataTemplate>
                </ListView.ItemTemplate>

            </ListView>

And here’s the ViewModel that updates it:

        private void UpdateStatusLog(string msg)
        {
            Log.Add(msg);
        }

If you add to the listview, what you should notice is that once you’ve filled it, you’ll start to add items off the bottom.

Behaviors (sic)

The Behaviors SDK is now available for WinRT. Once you’ve included it in your project, you get a number of build in behaviours and, you can create your own. Before you build your own, a base class will probably make you feel more at home (Reference):

    public abstract class Behaviour<T> : DependencyObject, IBehavior where T : DependencyObject
    {

        [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
        public T AssociatedObject { get; set; }

        protected virtual void OnAttached()
        {
        }

        protected virtual void OnDetaching()
        {
        }

        public void Attach(Windows.UI.Xaml.DependencyObject associatedObject)
        {
            this.AssociatedObject = (T)associatedObject;
            OnAttached();
        }

        public void Detach()
        {
            OnDetaching();
        }

        DependencyObject IBehavior.AssociatedObject
        {
            get { return this.AssociatedObject; }
        }
    }

Not least, because you can correct the spelling of Behaviour 🙂

ListView Behaviour

    public sealed class AutoScrollToLastItemBehavior : Behaviour<ListView>
    {
        // Need to track whether we've attached to the collection changed event
        bool _collectionChangedSubscribed = false;

        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.SelectionChanged += SelectionChanged;

            // The ItemSource of the listView will not be set yet, 
            // so get a method that we can hook up to later
            AssociatedObject.DataContextChanged += DataContextChanged;
        }

        private void SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ScrollIntoView();
        }

        private void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            ScrollIntoView();
        }

        private void DataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
        {
            // The ObservableCollection implements the INotifyCollectionChanged interface
            // However, if this is bound to something that doesn't then just don't hook the event
            var collection = AssociatedObject.ItemsSource as INotifyCollectionChanged;
            if (collection != null && !_collectionChangedSubscribed)
            {
                // The data context has been changed, so now hook 
                // into the collection changed event
                collection.CollectionChanged += CollectionChanged;
                _collectionChangedSubscribed = true;
            }

        }

        private void ScrollIntoView()
        {
            int count = AssociatedObject.Items.Count;
            if (count > 0)
            {
                var last = AssociatedObject.Items[count - 1];
                AssociatedObject.ScrollIntoView(last);
            }
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.SelectionChanged -= SelectionChanged;
            AssociatedObject.DataContextChanged -= DataContextChanged;

            // Detach from the collection changed event
            var collection = AssociatedObject.ItemsSource as INotifyCollectionChanged;
            if (collection != null && _collectionChangedSubscribed)
            {
                collection.CollectionChanged -= CollectionChanged;
                _collectionChangedSubscribed = false;

            }
        }

Attaching the behaviour

Finally, change the listview to include a call to the behaviour:

            <ListView ItemsSource="{Binding Log}" x:Name="StatusUpdate">                
                <i:Interaction.Behaviors>
                    <behaviours:AutoScrollToLastItemBehavior />
                </i:Interaction.Behaviors>
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding}"/>
                    </DataTemplate>
                </ListView.ItemTemplate>

            </ListView>

Also, you need to reference Interactivity, and your behaviours:

    xmlns:behaviours="using:KingMaker.Behaviours"    
    xmlns:i="using:Microsoft.Xaml.Interactivity" 

The listview should now behave as expected.

Creating and Binding to a User Control in MVVM Cross

While creating my game, I recently came across the problem of navigation. This post describes how to create a custom user control and react to the event inside.

The usual disclaimer still applies here; although this is an MVVM Cross post, the contents of it should be applicable for any MVVM Framework or, in fact, any XAML binding at all.

User Control

The user control that I’m going to use is simply a navigation bar to appear at the top of each screen.

The XAML for the user control is here:

<UserControl
    x:Name="NavigationControlRoot">
    
    <Grid DataContext="{Binding ElementName=NavigationControlRoot}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Button Content="Home" Grid.Column="0" Command="{Binding HomeClick}" />
        <Button Content="Back" Grid.Column="1" Command="{Binding BackClick}" />
    </Grid>
</UserControl>

So, I’ve got two commands, binding to the code behind. The key point here is that the root control (grid) binds to the DataContext of the user control – effectively this binds it to the containing DataContext. Here’s the code behind:


    public sealed partial class NavigationPanel : UserControl
    {
        public static DependencyProperty BackCommandProperty =
            DependencyProperty.Register(
                "BackClick",
                typeof(ICommand),
                typeof(NavigationPanel),
                new PropertyMetadata(null));

        public static DependencyProperty HomeCommandProperty =
            DependencyProperty.Register(
                "HomeClick",
                typeof(ICommand),
                typeof(NavigationPanel),
                new PropertyMetadata(null));

        public NavigationPanel()
        {
            this.InitializeComponent();
        }
        
        public ICommand BackClick
        {
            get
            {
                return (ICommand)GetValue(BackCommandProperty);
            }

            set
            {
                SetValue(BackCommandProperty, value);
            }
        }

        public ICommand HomeClick
        {
            get
            {
                return (ICommand)GetValue(HomeCommandProperty);
            }

            set
            {
                SetValue(HomeCommandProperty, value);
            }
        }        
    }

So, you’ve now exposed two dependency properties and bound them to the XAML in the user control.

Host App

Here’s the relevant XAML for the hosting view:

<controls:NavigationPanel BackClick="{Binding BackClickCommand}"                                  
                                  HomeClick="{Binding HomeClickCommand}"/>

And that just binds to the ViewModel as you would expect.

        private IMvxCommand _homeClickCommand;
        public IMvxCommand HomeClickCommand
        {
            get
            {
                if (_homeClickCommand == null)
                {
                    _homeClickCommand = new MvxCommand(() => GoHome());
                }
                return _homeClickCommand;
            }
            set
            {
                _homeClickCommand = value;
            }
        }

        private void GoHome()
        {
            ShowViewModel<MainViewModel>();
        }

For me, this is in a base view model, so it responds to the same command in every view.

Conclusion

I think the final version of this code will interact with an IMvxPresenter in some way, which may make another post.

Updating a View Model from Inside a Collection

My last post suggested a concept of having a `Selectable` Model, which effectively wraps a model in a class with a generic item and an `IsSelected` property. This does, however, present a slight issue. What if you want to update the view model, based on the item being selected, or de-selected?

Say, for example, that from my previous post, you had a property on the Person class called Wages, and wanted to display the total wages of all the selected people. You would have defined `TotalCostSummary` in the ViewModel, and bound it in the View.

My solution is to pass a delegate into the Selectable item. Here’s how I did it (this doesn’t really make any sense without referring back to the first post).

SelectableItem Model

In the `SelectableItem`, define a new property like so:

        private Action _updateMethod = null;
        public Action IsSelectedChangedMethod
        {
            get { return _updateMethod; }
            set
            {
                _updateMethod = value;
            }
        }

And change `IsSelected` to looks like this:

        private bool _isSelected;
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                _isSelected = value;                
                RaisePropertyChanged();
                
                if (_updateMethod != null)
                    _updateMethod();
            }
        }

ViewModel

        private void UpdateTotalCost()
        {
            _summary = SelectablePeople.Where(a => a.IsSelected).Sum(s => s.Item.Wages);
            RaisePropertyChanged(() => TotalCostSummary);
        }

Next, change the code to define the list:

List<Person> population = GetPeople();
SelectablePeople = new ObservableCollection<SelectableItem<Person>>(population
	.Select(n => new SelectableItem<Person>() 
	{ 
		Item = n, IsSelected = false, IsSelectedChangedMethod = (() => UpdateTotalCost())  
	}).ToList());

Conclusion

The net effect is that the changes now made inside the model can bubble up to the ViewModel, but the separation of the two has been maintained.

WinRT Data Binding Using MVVM

How to bind Windows 8 XAML to a View Model. Although this post is based on an example using MVVM Cross, it will work for any MVVM framework, or even a customised one.

The Problem

I have a collection of data that I want to display in a customised format. My architecture is MVVM (using MVVM Cross).

Architecture

The principle here is that my data is stored in a model, but shaped in the ViewModel into a digestible format for the view. In my specific example, I have a list of people, and based on a specific criteria, I want to display a selection of these people in the view. For the sake of this article, I want to display people with a name starting with “D”.

Implementation

My model looks something like this:

    public class Person
    {
        #region Basic attributes
        public string Name { get; set; }

When my ViewModel is shown, I override an initialise method. Whilst this is not part of MVVM Cross per-se, it is basically a call to a custom initialise from the default `Init`:

private IEnumerable<Person> _people;
public IEnumerable<Person> People
{
    get { return _people; }
    set
    {
        _people = value;
        RaisePropertyChanged(() => People);
    }
}

// Override custom init method
protected override void RealInit(NavigationParameter parameter)
{            
    var population = Mvx.Resolve<Population>();
    People = population.Where(p => p.Name.StartsWith("D"));
}

So, my ViewModel now contains the correct, shaped data, I can just bind this:

    <Page.Resources>
        <DataTemplate x:Name="PeopleTemplate">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}"/>
            </StackPanel>
        </DataTemplate>    
    </Page.Resources>

    …


    <ListView x:Name="ItemListView" 
                      ItemsSource="{Binding People}"
                      Width="Auto" Height="Auto" 
                      ItemTemplate="{StaticResource PeopleTemplate}" 
                      ShowsScrollingPlaceholders="False"                          
                      />

And that should work.

MVVMCross – ShowViewModel not working?

I thought I’d jot this down, as it had me for a short while. Imagine that you have a line of code that looks like this:

ShowViewModel<MyViewModel>();

But nothing happens when you call it.

The Output Window

The output window is definitely your friend with MVVMCross; it may say something like this:

mvx:Diagnostic: 36.44 Error seen during navigation request to MyViewModel – error KeyNotFoundException: Could not find view for MyApp.PCL.ViewModels.MyViewModel
at Cirrious.MvvmCross.Views.MvxViewsContainer.GetViewType(Type viewModelType)
at Cirrious.MvvmCross.WindowsStore.Views.MvxStoreViewPresenter.Show(MvxViewModelRequest request)

So, what’s the problem?

Some things to check: firstly, check that you are using an MVVMCross view; that is, for example, in Windows 8, you need your page to inherit from MvxStorePage, not Page:

Conclusion

Nothing here that you won’t see on one of Stuart Lodge’s tutorials, and probably a good handful of SO questions. So now it’s here as well.

Updating a Progress Bar using MVVM Cross

As usual with these posts, although the specific code in the article relates to MVVM Cross, it should be applicable to any MVVM framework. Where it is specific, I’ll try to flag that up.

The Scenario

In the current game that I’m writing in MVVM Cross (yes, that’s right – a game), I have a situation where the user selects to create a “New Game” and the game world needs to be generated. As this can take some time, I want to display a progress bar. Roughly speaking, the process flow is as follows:

On the Menu Page, the User selects “New Game”.
The Menu View Model calls a service that creates the game world.
It then calls the Main Page View Model to display the main page.

The Problem

Basically, communicating between view models without tightly coupling them together.

That’s what messages are for isn’t it?

Yes.

Here’s my implementation.

First step is to add the progress bar to the screen that you want to update:

<views:MvxStorePage
    x:Class=…
    xmlns:converters="using:MyGame.Converters"
    mc:Ignorable="d">

    <views:MvxStorePage.Resources>
        <converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConv"/>    
    </views:MvxStorePage.Resources>

    …

    <ProgressBar Value="{Binding LoadingProgress}" Maximum="{Binding TotalProgress}" Margin="20" Visibility="{Binding IsLoading, Converter={StaticResource BooleanToVisibilityConv}}"/>

There are three properties bound here: None exist yet. Obviously, if you want the progress bar to always display, you might not need all three.

Let’s create the properties in the VM:

        private bool _isLoading = false;
        public bool IsLoading
        {
            get { return _isLoading; }
            set
            {
                _isLoading = value;
                RaisePropertyChanged(() => IsLoading);
            }
        }

        private int _loadingProgress = 0;
        public int LoadingProgress
        {
            get { return _loadingProgress; }
            set
            {
                _loadingProgress = value;
                RaisePropertyChanged(() => LoadingProgress);
            }
        }

        private int _totalProgress = 0;
        public int TotalProgress
        {
            get { return _totalProgress; }
            set
            {
                _totalProgress = value;
                RaisePropertyChanged(() => TotalProgress);
            }
        }

You will also need to declare the BooleanToVisiblityConverter:

    public class BooleanToVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            return (bool)value ? Visibility.Visible : Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }

Now there’s something to bind to. Next, set-up the messenger.

Messenger

You need to register the messenger object. I have a base model that I do this in, but anywhere before you use it is fine:

Mvx.LazyConstructAndRegisterSingleton<IMvxMessenger, MvxMessengerHub>();

(Warning: MVVM Cross specific)
A caveat here; if you use something like `RegisterType` to register the messenger object, that will also (appear to) work. However, it won’t actually work; it will create a fresh instance of the messenger object each time. If you decide to do it that way then you will need to inject the messenger object into the subscriber and publisher (it has to be the same instance).

Next, you need to create the message:

    class UpdateProgressMessage : MvxMessage
    {
        public UpdateProgressMessage(object sender, int currentProgress, int totalProgress) : base(sender)
        {
            CurrentProgress = currentProgress;
            TotalProgress = totalProgress;
        }

        public int CurrentProgress { get; set; }
        public int TotalProgress { get; set; }
    }

This isn’t much, but the important thing is the constructor. Okay, now let’s subscribe to that message at the start of the task:

_subscriptionTag = Messenger.Subscribe<UpdateProgressMessage>(UpdateProgress);

(A note on `_subscriptionTag` later)

`UpdateProgress` is a method defined like this:

        private void UpdateProgress(UpdateProgressMessage updateProgressMessage)
        {            
            LoadingProgress = updateProgressMessage.CurrentProgress;
            TotalProgress = updateProgressMessage.TotalProgress;
            IsLoading = (updateProgressMessage.CurrentProgress > 0 &amp;&amp; 
                updateProgressMessage.TotalProgress != updateProgressMessage.CurrentProgress);

        }

Notice that you accept the `UpdateProgressMessage`.

That note on `_subscriptionTag`

Firstly, _subscriptionTag is a class level variable, defined like this:

private MvxSubscriptionToken _subscriptionTag;

Once the task is complete you can unsubscribe. For MVVM Cross specifically, the subscription uses weak references, meaning that as soon as `_subscriptionTag` goes out of scope, it will be garbage collected, and will effectively unsubscribe (which is why it needs to be class level in the first place). Having said that, personally, I prefer things to happen in code when I tell them to, and not at some undefined and unpredictable point in the future; so, to unsubscribe:

Messenger.Unsubscribe<UpdateProgressMessage>(subscriptionTag);

Publish

Finally, just wire in the publish code. I have a helper method that instantiates the services and calls the game setup code, but this should work anywhere in the application:

Messenger.Publish<UpdateProgressMessage>(new UpdateProgressMessage(this, count, total));

Because `IMvxMessenger` is registered as a singleton, once you resolve it, you should be able to publish this from anywhere.

A Word About Threading

Okay, so this will all work, but where the task runs on the UI thread, you probably won’t see it update. Consequently, I start a new task for my long running process. Remember that if you do this, then subscribing to messages on the main thread may not work.

Conclusion

Okay, so now I have a progress bar for the set-up of my game. Like I said at the start, I think this should work for any architecture that supports IoC and messaging, but MVVM Cross seems to handle this very neatly.