Page Navigation using Messaging Center

Messaging Center
Messaging Center- Image used from https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/messaging-center

MessagingCenter doesn’t need any introduction in this world of Xamarin. As the name suggests, it is clearly used for Messages. Now the question arises What Messages? Are these Chats? Who is Sending? Who is Receiving? etc…etc…etc…

Let’s look at the gist of Messaging Center from here:
The publish-subscribe pattern is a messaging pattern in which publishers send messages without having knowledge of any receivers, known as subscribers. Similarly, subscribers listen for specific messages, without having knowledge of any publishers. You can read more about the common explanation here. If you are still not aware of MessagingCenter, then kindly read this Documentation on MessagingCenter.

We know that while using MessagingCenter, there are two actors in the scene, Publisher and Subscriber. Now, what happens is that the Subscriber subscribes for a specific message and performs an action whenever the Publisher publishes the desired message.

Now let’s look at the use case for this:
We always see this question arising wherein the developers are trying to perform operations on Page Navigation from the ViewModel like Navigation.PushAsync, Navigation.PushModalAsync, Navigation.PopAsync or Navigation.PopModalAsync etc. However, we all know that the Navigation property is only accessible as part of the Page.

The sole reason behind using frameworks like MVVM is to isolate the View from ViewModel. Consider the scenario where we have a ListView and in its header is the Add Button. Now, this Add Button is bound to the Add Command in the ViewModel which needs to perform the function call of Navigation.PushModalAsync().

So here when we think about performing operations like PushModalAsync, the challenge is that we cannot just go ahead and use the Navigation object unless we store the Root/Parent page somewhere in another variable, etc.

If you create a New Blank Xamarin.Forms App with Master Page, you will get a templated App with few lines of code.
In your MainPage constructor, you can try this:

public partial class MainPage : MasterDetailPage
{
    Dictionary MenuPages = new Dictionary();
    public MainPage()
    {
        InitializeComponent();
        MasterBehavior = MasterBehavior.Popover;

        //Subscribing to the Message NavTo
        MessagingCenter.Subscribe("AppName", "NavTo", async (sender, arg) =>   
        {
            await NavigateFromMenu(arg);
        });
    }
 
    public async Task NavigateFromMenu(int id)
    {
        if (!MenuPages.ContainsKey(id))
        {
            switch (id)
            {
                case (int)MenuItemType.Home:
                    MenuPages.Add(id, new NavigationPage(new HomePage()));
                    break;
                case (int)MenuItemType.About:
                    MenuPages.Add(id, new NavigationPage(new AboutPage()));
                    break;
                case (int)MenuItemType.Add:
                    MenuPages.Add(id, new NavigationPage(new AddPage()));
                    break;
            }
        }

        var newPage = MenuPages.ContainsKey(id) ? MenuPages[id] : null;
        if (newPage != null && Detail != newPage)
        {
            Detail = newPage;
            IsPresened = false;
        }
    }
} 

Now we can send the Message from our MainViewModel like this:

private void AddCommand(object obj)
{
    MessagingCenter.Send<string, int>("AppName", "NavTo", (int)MenuItemType.Add);
    //MenuItemType is an Enum.
}

In the above example, the AddCommand sends a Message of NavTo with the Add Parameter. The main page which is already subscribed to this will try to Navigate based on the parameters provided.

As shown above, you can easily perform Page Navigation using MessagingCenter.

Happy Coding!!!