页面消失后如何取消订阅事件
How to unsubscribe from Event after a Page disappear
从显示 DATA 的页面的 viewModel 中,我需要显示一个 SecondaryPage,其中包含这些 DATA 的子集。因此,当单击按钮时,我将过滤器应用于数据并调用 SecondaryPage。当 secondPage 消失时,我传递了一个回调来重置过滤器:
private async Task levelClickedAction(object arg)
{
var level = arg as Observable<string>;
if (level == null) return;
// Unselect the clicked item
LevelClicked = null;
isHidden = true; // Prevent from updating primary page
// Apply filter to the data
wordDictionary.SetReviewPlanFilter( Reviews.IndexOf(level) );
// Create secondary page, setup callback and display it
var page = new SecondaryPage();
page.OnDisappearingEvent += ResertFilters;
await Application.Current.MainPage.Navigation.PushModalAsync(new NavigationPage(page));
}
private void ResetFilters(object sender, object e)
{
isHidden = false;
wordDictionary.ResetReviewPlanFilter();
}
我的问题是:
- 我是否需要取消订阅 OnDisappearingEvent 以确保
SecondaryPage 是否正确处理?看来,是的,我这样做是因为处理程序的强大引用和主页的更长生命周期。正确吗?
- 那么如何去做,何时何地?
我曾尝试在 PushModalAsync(new NavigationPage(page))
之后使用 .ContinueWith()
但它立即被触发...
问题是在 ResetFilters 过程中,我不知道该页面了......我可以创建一个字段而不是 var 页面:
private WordList page;
...
private void ResetFilters(object sender, object e)
{
isHidden = false;
page.OnDisappearingEvent -= ResetFilters;
page = null;
wordDictionary.ResetReviewPlanFilter();
}
但是看起来很难看...有更多的beautifull/straighforward方式吗?
感谢您的建议。
好的,我找到了我一直在寻找的更好的方法。它不需要调整目标 SecondaryPage
我为我的 ViewModel 创建了一个界面:
public interface IReturnCallback
{
Action OnReturnCallback {get; set; }
}
然后我将调用页面的 .xaml.cs 文件改编成这样:
protected override void OnAppearing()
{
// Invoke callback if any
((IReturnCallback)BindingContext)?.OnReturnCallback?.Invoke();
base.OnAppearing();
}
因此,每当我从一个页面返回时必须执行代码时,我都会在调用 SecondaryPage 之前在 OnReturnCallback 中分配它:
private async Task levelClickedAction(object arg)
{
var level = arg as Observable<string>;
if (level == null) return;
// Unselect the clicked item
LevelClicked = null;
isHidden = true; // Prevent from updating primary page
// Apply filter to the data
wordDictionary.SetReviewPlanFilter( Reviews.IndexOf(level) );
// Create secondary page, setup callback and display it
if (page == null) page = new WordList();
OnReturnCallback = () => {
isHidden = false;
wordDictionary.ResetReviewPlanFilter();
OnReturnCallback = null;
};
await Application.Current.MainPage.Navigation.PushModalAsync(new NavigationPage(page));
}
不要忘记重置 OnReturnCallback,这样它只会被调用一次。
有什么意见吗?
从显示 DATA 的页面的 viewModel 中,我需要显示一个 SecondaryPage,其中包含这些 DATA 的子集。因此,当单击按钮时,我将过滤器应用于数据并调用 SecondaryPage。当 secondPage 消失时,我传递了一个回调来重置过滤器:
private async Task levelClickedAction(object arg)
{
var level = arg as Observable<string>;
if (level == null) return;
// Unselect the clicked item
LevelClicked = null;
isHidden = true; // Prevent from updating primary page
// Apply filter to the data
wordDictionary.SetReviewPlanFilter( Reviews.IndexOf(level) );
// Create secondary page, setup callback and display it
var page = new SecondaryPage();
page.OnDisappearingEvent += ResertFilters;
await Application.Current.MainPage.Navigation.PushModalAsync(new NavigationPage(page));
}
private void ResetFilters(object sender, object e)
{
isHidden = false;
wordDictionary.ResetReviewPlanFilter();
}
我的问题是:
- 我是否需要取消订阅 OnDisappearingEvent 以确保 SecondaryPage 是否正确处理?看来,是的,我这样做是因为处理程序的强大引用和主页的更长生命周期。正确吗?
- 那么如何去做,何时何地?
我曾尝试在 PushModalAsync(new NavigationPage(page))
之后使用 .ContinueWith()
但它立即被触发...
问题是在 ResetFilters 过程中,我不知道该页面了......我可以创建一个字段而不是 var 页面:
private WordList page;
...
private void ResetFilters(object sender, object e)
{
isHidden = false;
page.OnDisappearingEvent -= ResetFilters;
page = null;
wordDictionary.ResetReviewPlanFilter();
}
但是看起来很难看...有更多的beautifull/straighforward方式吗?
感谢您的建议。
好的,我找到了我一直在寻找的更好的方法。它不需要调整目标 SecondaryPage
我为我的 ViewModel 创建了一个界面:
public interface IReturnCallback
{
Action OnReturnCallback {get; set; }
}
然后我将调用页面的 .xaml.cs 文件改编成这样:
protected override void OnAppearing()
{
// Invoke callback if any
((IReturnCallback)BindingContext)?.OnReturnCallback?.Invoke();
base.OnAppearing();
}
因此,每当我从一个页面返回时必须执行代码时,我都会在调用 SecondaryPage 之前在 OnReturnCallback 中分配它:
private async Task levelClickedAction(object arg)
{
var level = arg as Observable<string>;
if (level == null) return;
// Unselect the clicked item
LevelClicked = null;
isHidden = true; // Prevent from updating primary page
// Apply filter to the data
wordDictionary.SetReviewPlanFilter( Reviews.IndexOf(level) );
// Create secondary page, setup callback and display it
if (page == null) page = new WordList();
OnReturnCallback = () => {
isHidden = false;
wordDictionary.ResetReviewPlanFilter();
OnReturnCallback = null;
};
await Application.Current.MainPage.Navigation.PushModalAsync(new NavigationPage(page));
}
不要忘记重置 OnReturnCallback,这样它只会被调用一次。
有什么意见吗?