maui

How to use WeakReferenceMessenger in MAUI?


I didn't get a clear picture of how to use WeakReferenceMessenger in MAUI after reading this blog.

I am using MessagingCenter in my xamarin forms app like below.

//Send message
MessagingCenter.Send<ModePage>(this, "modechanged");

//Subscribe message and actions
MessagingCenter.Subscribe<ModePage>(this, "modechanged", (sender) =>
{
    SetMode();
});

Please show me the equivalent usage of the above code using WeakReferenceMessenger? In WeakReferenceMessenger where I need to pass the key and to subscribe with key?


Solution

  • MessagingCenter has been deprecated in .NET 7 and replaced with WeakReferenceMessenger in the CommunityToolkit.Mvvm NuGet package.

    Below are the detailed steps on how to use WeakReferenceMessenger in MAUI:

    1. Install the CommunityToolkit.Mvvm NuGet package into your project.

    2. Define a message class: SendItemMessage.cs that you want to send across different parts or pages of your MAUI app like below:

    public class SendItemMessage : ValueChangedMessage<string> 
    {
        public SendItemMessage(string value) : base(value)
        {
        }
    }
    
    1. Sending the messages: You need to pass an instance of the message class to the Send method like below:
    WeakReferenceMessenger.Default.Send(new SendItemMessage("Model Changed"));
    
    1. Receiving the messages: You need to register a message handler for the message class like below:
    WeakReferenceMessenger.Default.Register<SendItemMessage>(this, (r, m) =>
    {
         OnMessageReceived(m.Value);
    });
    

    Here's the sample code below for your reference:

    MainPage.cs:

    public partial class MainPage : ContentPage 
    {
          public MainPage(MainPageViewModel viewModel)
          {
                InitializeComponent();
                BindingContext = viewModel;
          }
    
          private void OnCounterClicked(object sender, EventArgs e)
          {
                WeakReferenceMessenger.Default.Send(new SendItemMessage("Model Changed"));
          }
    }
    

    MainPage.xaml:

    <Button 
        x:Name="CounterBtn"
        Text="Click me"
        Clicked="OnCounterClicked"
        HorizontalOptions="Center" />
    

    MainPageViewModel.cs:

    public class MainPageViewModel
    {
            public  MainPageViewModel()      
            {
                WeakReferenceMessenger.Default.Register<SendItemMessage>(this, (r, m) =>
                {
                    OnMessageReceived(m.Value);
                });            
            }
    
            private static void OnMessageReceived(string value)
            {
                Shell.Current.DisplayAlert("Messages received", value, "OK");
            }
    }
    

    Another cool way to register message handlers by using the IRecipient<TMessage> interface to register message handlers.

    public class MainPageViewModel: IRecipient<SendItemMessage> 
    {
            public  MainPageViewModel()            
            {
    
                WeakReferenceMessenger.Default.Register(this);  
            }
    
            public void Receive(SendItemMessage message)
            {
                Shell.Current.DisplayAlert("Messages received", message.Value, "OK");
             }
        }
    

    Update:

    public class SendItemMessage : ValueChangedMessage<string> 
    {
        public SendItemMessage(string value) : base(value)
        {
        }
    }
    

    The ValueChangedMessage<T> class is a generic class that represents a message that contains a value of type T that has been changed. Since the SendItemMessage implements the ValueChangedMessage<string>, the generic parameter <string> specifies the type of the value that the message carries. In the example above, the value is a string. You can define the type of the value according to your own design, like a simple datatype:int,bool, or even a class model, etc.