Vipin Krishna
Vipin Krishna

Reputation: 365

Xamarin Forms MessagingCenter Subscribe called two times

I'm clicking on a product item in listview in product page viewmodel to show a popup(using rg.plugin popup) for selecting one of the product variants.After selecting variant,i am sending the selected variant to product page using messagingcenter from variant popup page viewmodel,subscribed in product page viewmodel constructor. working fine there.when i navigate to the previous page and then came back to this product page for adding one or more variant to the same previously selected product,Messagingcenter subscribe called twice and product value increased twice.Tried to subscribe in the product page onappearing and unsubscribe in disappearing method.still calling two times? How to solve this issue?

calling popup:

               var result = await dataService.Get_product_variant(store_id, product_id);
                if (result.status == "success")
                {
                    ind_vis = false;
                    OnPropertyChanged("ind_vis");

                    App.Current.Properties["product_variant_result"] = result;
                    App.Current.Properties["cartitems"] = purchaselist;
                    App.Current.Properties["selected_product"] = product_List2 ;
                    await PopupNavigation.Instance.PushAsync(new Popup_variant());                   
                }

popup viewmodel: sending message

        public Popup_variant_vm()
        {
            Radio_btn = new Command<Product_variant_list2>(Radio_stk_tapped);
            product_variant_list = new List<Product_variant_list2>();
            purchaselist = new ObservableCollection<Product_list2>();                       
            show_variants();            
        }

        internal void Confirm_variant()
        {
            if(App.Current.Properties.ContainsKey("selected_variant"))
            {
                 MessagingCenter.Send<Popup_variant_vm, object>(this, "selected_variant", App.Current.Properties["selected_variant"]); //Message send from popup to product page                    
            }
            else
            {
                DependencyService.Get<IToast>().LongAlert("Please select any size");
            }
        }

product page viewmodel: subscribed here..called twice when navigating from previous page to this

    public Store_page()
    {
       InitializeComponent();
    }
    protected override void OnAppearing()
    {
        base.OnAppearing();

        var vm = new store_page_vm();
        vm.Navigation = Navigation;
        BindingContext = vm;

        MessagingCenter.Unsubscribe<Popup_variant_vm, object>(this, "selected_variant");
        MessagingCenter.Subscribe<Popup_variant_vm, object>(this, "selected_variant",async (sender, selected_variant) =>
        { 
            var vm1 = BindingContext as store_page_vm;
            vm1?.Addcart2(selected_variant);// called twice
        });            
    } 

unsubscribed in product cs page

protected override void OnDisappearing()
        {
            var vm = BindingContext as store_page_vm;
            vm?.Save_cart();    
            MessagingCenter.Unsubscribe<Popup_variant_vm>(this, "selected_variant");    
        }

Upvotes: 3

Views: 3898

Answers (5)

Yogeshwaran Kumar
Yogeshwaran Kumar

Reputation: 1

Changing Messagingcenter in to single subscription.

public class Messagingcenter_singleton
{
    private static Messagingcenter_singleton _instance;
    private bool isActivated = false;
    private Action<string> callBackFun = null;
    public static Messagingcenter_singleton Instance()
    {
        if (_instance == null)
        {
            _instance = new Messagingcenter_singleton();
        }
        return _instance;
    }

    public void setCallBack(Action<string> eventCallBack)
    {
        callBackFun = eventCallBack;
    }

    public void startSubscribe()
    {
        if (!isActivated)
        {
            isActivated = true;
            MessagingCenter.Subscribe<string, string>(this, "Name", eventCallBack);
        }
    }

    private void eventCallBack(string arg1, string arg2)
    {
        if (callBackFun != null)
        {
            InvokeMethod(new Action<string>(callBackFun), arg2);
        }
    }

    public static object InvokeMethod(Delegate method, params object[] args)
    {
        return method.DynamicInvoke(args);
    }

}

Use Below Code in you view model class

public void initSubscribe()
{
   Messagingcenter_singleton.Instance().startSubscribe();
   Messagingcenter_singleton.Instance().setCallBack(eventCallBack)
}

public void eventCallBack(string arg2)
{
// write your code here
}

Upvotes: 0

Divyesh
Divyesh

Reputation: 2415

I have created static counter variable in my app the in subscriber I have done this:


public static class Constants
{
    public static int msgCenterSubscribeCounter { get; set; } = 0;
}

MessagingCenter.Subscribe<object, string>(this, "hello", (sender, arg) =>
{
    Constants.msgCenterSubscribeCounter++;
    if (arg.Equals("hello") && Constants.msgCenterSubscribeCounter == 1)  
    {
        // handle your logic here
    }
});

Reset counter in OnDisappearing() method from where you have called Send.

Upvotes: 0

user14708696
user14708696

Reputation: 1

My solution:

put unsubscribe sentence into subscribe body !!

 MessagingCenter.Subscribe<object, string>(this, "IdSearch", (sender, arg) =>
            {
              

                listView.ItemsSource = arg;

                MessagingCenter.Unsubscribe<object, string>(this, "IdSearch");

            }, BindingContext);

Upvotes: 0

FreakyAli
FreakyAli

Reputation: 16572

Your unsubscription should look something like below and it should work :

  MessagingCenter.Unsubscribe<Popup_variant_vm, object>(this, "selected_variant");

Upvotes: 1

Daxa Varsani
Daxa Varsani

Reputation: 156

https://stackoverflow.com/a/44753021/10937160

try this, and make sure you do not call Subscribe more than once.

Upvotes: 0

Related Questions