Форма Xamarin Отмена подписки MessagingCenter не работает должным образом
Функциональность, написанная внутри MessagingCenter.Subscribe(), вызывается несколько раз, когда я перемещаюсь туда и обратно несколько раз в приложении. Но каждый раз перед подпиской я отменяю подписку на то же самое в конструкторе, как показано ниже, но это не сработало.
MessagingCenter.Unsubscribe<SubmitPage>(this,"Save");
MessagingCenter.Subscribe<SubmitPage>(this, "Save", (sender) =>
{
DisplayToastOnSuccessfulSubmission();
});
В моем приложении у меня есть 6 страниц ( git), и я сохраняю данные на 6-й странице с помощью MessagingCenter.Send, и то же самое будет подписано на 2-й странице, а сохраненное сообщение будет отображаться на 2-й странице (после перехода на эту страницу).
Теперь я перемещаюсь как 2->1->2->3->4->5->6 в этом конкретном случае DisplayToastOnSuccessfulSubmission() будет вызван два раза (потому что конструктор Page2 вызывается дважды).
Я даже пытался поместить тот же код в OnAppearing. Я не могу отменить подписку в OnDisappear, так как мне нужно, чтобы проводка события была до того момента, когда я достигну Page6 для сохранения.
Воспроизведено то же поведение в примере проекта и добавлено здесь https://github.com/suchithm/MessageCenterSampleApp
Drop box link
Как правильно это сделать?
4 ответа
Но каждый раз перед подпиской я отменяю подписку на то же самое в конструкторе, как показано ниже, но это не сработало.
MessagingCenter.Subscribe()
вызывается несколько раз, потому что в вашем коде есть два экземпляра Page2, оба они используют MessagingCenter.Subscribe()
метод, поэтому Unsubscribe
не работал
Вы можете изменить page2()
в одиночку, чтобы убедиться, что есть только один экземпляр Page2
в вашем проекте, после этого, когда вы отправляете сообщение, MessagingCenter.Subscribe()
вызывается только один раз.
Page2.cs:
public static Page2 instance = new Page2();
public static Page2 GetPage2Instance()
{
if(instance == null)
{
return new Page2();
}
return instance;
}
private Page2()
{
InitializeComponent();
MessagingCenter.Unsubscribe<Page2>(this, "SaveToastPage2");
MessagingCenter.Subscribe<Page2>(this, "SaveToastPage2", (sender) =>
{
DisplayToastOnSuccessfulSubmission();
}
}
Когда вы отправляете сообщение:
MessagingCenter.Send(Page2.GetPage2Instance(), "SaveToastPage2");
РЕДАКТИРОВАТЬ:
Помните, что объявление конструкторов Page2
класс, чтобы быть частным, чтобы убедиться, что есть только один экземпляр Page2
в вашем проекте уверен.
private Page2()
{
...
}
Изменить ваш Page1.cs
код:
async void Handle_Next(object sender, System.EventArgs e)
{
await App.NavigationRef.PushAsync(Page2.GetPage2Instance(), true);
}
Я столкнулся с той же проблемой. Я решил проблему, передав те же параметры inn subscribe и unsubscribe.
MessagingCenter.Subscribe<Page1, T>(this, "Listen", async (Page1 arg1, T
listenedString) =>
{
});
Отпишитесь, как показано ниже
MessagingCenter.Unsubscribe<Page1, T>(this, "Listen");
I'm using this temporary solution.I declared a static dictionary to storage my object (to this example I used an object type).
private static Dictionary<string, object> subscribedReferencePages = new Dictionary<string, object>();
And I always storage the last subscribed page reference. Then I compare the page reference before triggering the message method to fire only the last one.
subscribedReferencePages[pageName] = this;
MessagingCenter.Subscribe<ViewModelBase>(this, pageName, async (sender) =>
{
if (!ReferenceEquals(sender, this))
{
return;
}
this.OnInitialized();
});
To call the message method I need to pass the dictionary as parameter (instead of the "this" reference).
MessagingCenter.Send(subscribedPages[pageName], keyPageName);
Вместо того, чтобы отписаться при переходе на страницу, отмените подписку при переходе в сторону ОТ страницы. В этот момент ваш экземпляр "этого" остается тем же "этим", как вы думаете.