MessagingCenter weird behavior

RodrigoJuarez.1796RodrigoJuarez.1796 USMember ✭✭
edited July 26 in Xamarin.Forms

In my current project I didn't understand some behaviors using the messagingcenter, so, I created a test project to explore how is working

I created a page with a button and a viewmodel with a command, when you tap in the button, the viewmodel send a message to the page, and the page write a line to the output and add a control to a stack layout

At that moment, everything is working fine

But if you go back and enter in the view again n times, and tap in the button, the message will be sent n times, the line in the output will happen n times, but the control in the stack layout will be added just one time, but the number of childrens in the stack layout will be n (you will see just one)

I think that the creation of the subscription is stacking, but I don't understand why, because I'm creating a new page every time

This is my ViewModel

public class MessagingCenterCallAndReturnViewModel
{

    public ICommand CallViewCommand { get; set; }

    public MessagingCenterCallAndReturnViewModel()
    {
        CallViewCommand = new Command(CallView);
    }

    public void CallView()
    {
        Debug.WriteLine("Sending Message to the View");
        Device.BeginInvokeOnMainThread(() =>
        {
            MessagingCenter.Send(this, "CallViewFromViewModel");
        });
    }

}

This is the code behind for the page

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MessagingCenterCallAndReturnPage : ContentPage
{
    public MessagingCenterCallAndReturnPage()
    {
        InitializeComponent();
        // MessagingCenter.Unsubscribe<MessagingCenterCallAndReturnViewModel>(this, "CallViewFromViewModel"); // This will not do anything

        ReportStackLayout.Children.Clear();
    }

    public void HandleCall(MessagingCenterCallAndReturnViewModel sender)
    {
        // You will enter multiple times here, but only one item will be added to the ReportStackLayout, but the children count will show the total times you entered here
        Debug.WriteLine("Handling Call from ViewModel");
        var count = ReportStackLayout.Children.Count;
        ReportStackLayout.Children.Add(new Label { Text = $"Handling Call from ViewModel {count}" });
    }

}

Attached image with the output

You can see the code in https://github.com/rodrigojuarez/XamMessagingCenterExploration

The question is, why is this happening? Is this a bug in xamarin.forms?

Posts

  • LarsNymandLarsNymand DKMember ✭✭

    First I think you need to move your MessagingCenter.Subscribe from MainPage to MessagingCenterCallAndReturnPage. Perhaps in the OnAppearing method.
    MessagingCenter.Subscribe(page, "CallViewFromViewModel", page.HandleCall);

    And then you should cleanup after you and add the MessagingCenter.Unsubscribe to the OnDisappearing method of MessagingCenterCallAndReturnPage.

    At least that's how I do it.

    Regarding the navigating back and forward, I think it has something to do with how Xamarin.Forms disposes pages that's left.
    I'm not sure how this works. I have seen something similar but never got the time to investigate if this is on purpose (maybe left for the GC to cleanup?) or if I have something in my code preventing it from removing the page object completely.

    Nevertheless I think it would be a good practice to tell MessagingCenter that you don't want to subscribe for that event anymore.

  • RodrigoJuarez.1796RodrigoJuarez.1796 USMember ✭✭

    You were right, after adding the unsubscribe in the OnDisappearing is working fine
    I just updated the github repo for anyone in need of the code

  • Gigex42Gigex42 USMember ✭✭✭

    @RodrigoJuarez.1796 please set @LarsNymand answer as correct

  • RodrigoJuarez.1796RodrigoJuarez.1796 USMember ✭✭

    @Gigex42 said:
    @RodrigoJuarez.1796 please set @LarsNymand answer as correct

    How can I do that?

Sign In or Register to comment.