Messaging center subscription hit twice in viewmodel

When I send a message, rg.plugin.popup is closed and MessagingCenter sends a message. ViewModel listens to it. Message is sent only once, but MessagingCenter.Subscribe get's it twice.

OnButtonClick function, from where message is sent:

         private async void Button_Clicked(object sender, EventArgs e)
                {
                    Console.WriteLine("Sent once");
                    MessagingCenter.Send<QuantityPopupView, List<string>>(this, "QuantityUpdate", new List<string>() { quantityEntry.Text, _id_Product });
                    await Rg.Plugins.Popup.Services.PopupNavigation.Instance.PopAsync();
                }

ViewModel, where message is subscribed to:

        // command declaration
        public IAsyncCommand<List<string>> OnQuantityChangedCommand { get; set; }

        // constructor
        public CartViewModel() {
        . . .
        OnQuantityChangedCommand = new AsyncCommand<List<string>>(ExecuteOnQuantityChangedCommand);
                    MessagingCenter.Subscribe<QuantityPopupView, List<string>>(this, "QuantityUpdate", (sender, arg) =>
                    {
                        OnQuantityChangedCommand.Execute(arg);
                    });
        . . . 
        }

        // function, which gets executed
                private async Task ExecuteOnQuantityChangedCommand(List<string> obj)
                {
                    Console.WriteLine("In ExecuteOnQuantityChangedCommand");
        }

// I pressed the button two times, note the execution time

Tried to unsubscribe from message, added bool, which was set to true, when message was received, but debugger breakpoint hit it twice anyway!

Best Answer

Answers

  • LandLuLandLu Member, Xamarin Team Xamurai

    If you only subscribed the messaging center once it won't be triggered twice.
    Please check whether there're two ViewModels in your hierarchy. Maybe, you initialized the same view model for twice and one of them has no functionality.
    Modify your printing code like:

    Debug.WriteLine($"In ExecuteOnQuantityChangedCommand\nlocation:{this.GetHashCode()}");
    

    It will help you make sure if the commnads belong to the same instance.

  • rozman50rozman50 Member ✭✭

    I looked through my code, and I couldn't find any initialization of this VM, except in xaml.cs like so:

        CartViewModel vm;
        public CartPage ()
        {
            InitializeComponent ();
            BindingContext = vm = new CartViewModel();
        }
    

    This is what debug.writeline tells me on execution:

    [0:] Sent once
    [0:] In ExecuteOnQuantityChangedCommand
    location:1151791462
    [0:] In ExecuteOnQuantityChangedCommand
    location:-397316206

  • rozman50rozman50 Member ✭✭

    @LandLu you were right

    I had it initialized twice. I had it initialized in AppShell.xaml, just for testing purposes, to see what multiple tabs looks like.

        <TabBar>
            <Tab Title="Products" Icon="search96_white.png">
                <ShellContent>
                    <views:ProductsPage />
                </ShellContent>
            </Tab>
            <Tab Title="Cart" Icon="cart96_white.png">
                <ShellContent>
                    <views:CartPage />
                </ShellContent>
            </Tab>
            <Tab Title="Settings" Icon="settings96_white.png">
                <ShellContent>
                    <views:CartPage />
                </ShellContent>
            </Tab>
        </TabBar>
    

    Solution: I removed last tab (with title Settings) and now it works. I didn't know, that doing this initializes new viewmodel!

Sign In or Register to comment.