How to MessagingCenter.Subscribe to same message from multiple senders

cmeerencmeeren USMember ✭✭
edited September 2016 in Xamarin.Forms

I want to subscribe to a message that can be sent from multiple ViewModels. Is there a more elegant solution than subscribing individually for each ViewModel, like I do below?

MessagingCenter.Subscribe<Page1Model, bool>(this, "SomeMessage", MyMethod);
MessagingCenter.Subscribe<Page2Model, bool>(this, "SomeMessage", MyMethod);

Best Answer

Answers

  • rudyrykrudyryk RUMember ✭✭✭
    edited October 2016

    As I understand, you're not limited to sent whatever you want from any place you want with the MessagingCenter :) For example, it could be an application-wide message:

    MessagingCenter.Subscribe<Application, bool>(this, "SomeMessage", MyMethod);
    

    add for sending

    MessagingCenter.Send(Application.Current, "SomeMessage", true);
    

    Of course, it's clearer if application-wide messages are sent from an application class code. I usually try to send messages from domain-specific models, like AuthManager, ChatConnectionManager etc.

  • cmeerencmeeren USMember ✭✭

    If I were to use Application, then I'm tying my view models to my view. Also, it becomes harder to test the VMs directly.

    Thanks for the tip on using domain-specific models, I'll keep that in mind.

  • Nicolas.BodinNicolas.Bodin USMember ✭✭

    The @RobertMcIntosh answer is really good but I want to share my solution :)

    Like the accepted answer I wrap the MessagingCenter inside my own class :

    void SubscribeToDoAction<T>() where T : class
    {
        MessagingCenter.Subscribe<T>(this, "message", (sender) => 
        {
            ( your action ... )
        });
    }
    

    The way to send the message is exactly the same as usual, it does not matter what class is sending (Sender1, Sender2, ...)

    MessagingCenter.Send(this, "message");

    And I subscribe to it like this :

    SubscribeToDoAction<Sender1>();
    SubscribeToDoAction<Sender2>();

  • _XANDER__XANDER_ Member ✭✭

    Without sending arguments:

    // Subscribe
    MessagingCenter.Subscribe<object>(this, "Arrived", (sender) =>
    {
        // Do something whenever the "Arrived" message is sent from whatever type <object> is.
    });
    
    // Send
    MessagingCenter.Send<object>(this, "Arrived");
    
    // Unsubscribe
    MessagingCenter.Unsubscribe<object>(this, "Arrived");
    

    With sending arguments:

    // Subscribe
    MessagingCenter.Subscribe<object, string>(this, "Arrived", (sender, arg) =>
    {
        // Do something whenever the "Arrived" message is sent from whatever type <object> is.
        myEntry.Text = arg;
    });
    
    // Send
    MessagingCenter.Send<object, string>(this, "Arrived", "New String");
    
    // Unsubscribe
    MessagingCenter.Unsubscribe<object, string>(this, "Arrived");
    
    // Source: gist.github.com/Driv4r/b82dec31f8e10495d6f2de62ab85ee4e
    

    The alternative way is to create a class that has nothing to do with either class that's sending or subscribing to the message. It could be as simple as a marker class or a class that has no properties or functions:

    // Subscribe
    MessagingCenter.Subscribe<LoginMessage>(this, "successful_login", (lm) => HandleLogin(lm));
    
    // Send
    MessagingCenter.Send<LoginMessage>(new LoginMessage, "successful_login");
    
    // Source: codemilltech.com/messing-with-xamarin-forms-messaging-center/
    

    p.s. Cannot post links at the moment, that is why via comments.

  • JassimRahmaJassimRahma USMember ✭✭✭✭

    I am still not clear on this guys

    I want to Send:

    MessagingCenter.Send(this, "Country", country_code);
    

    and...

    MessagingCenter.Send(this, "Country", country_name);
    

    to the Signup page

    How can I do that please?

Sign In or Register to comment.