【问题标题】:How to unsubscribe from Event after a Page disappear页面消失后如何取消订阅事件
【发布时间】:2021-03-07 14:42:34
【问题描述】:

从显示 DATA 的页面的 viewModel 中,我需要显示 SecondaryPage,其中包含这些 DATA 的子集。因此,当单击按钮时,我将过滤器应用于 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 proc 中,我不再知道该页面...然后我可以创建一个字段而不是 var 页面:

private WordList page;
...
private void ResetFilters(object sender, object e)
{
    isHidden = false;
    page.OnDisappearingEvent -= ResetFilters;
    page = null;
    wordDictionary.ResetReviewPlanFilter();
}

但它看起来很丑......有没有更漂亮/更直接的方式?

感谢您的建议。

【问题讨论】:

  • 为了完整起见,在我的辅助页面中我添加了:公共事件 EventHandler OnDisappearingEvent; protected override void OnDisappearing() => OnDisappearingEvent?.Invoke(this, EventArgs.Empty);

标签: events xamarin.forms callback ondisappearing


【解决方案1】:

好的,我找到了一个更好的方法,我正在寻找它。不需要适配目标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();
}

因此,每当我从一页返回时必须执行代码时,我都会在 OnReturnCallback 中分配它,然后像这样调用 SecondaryPage:

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,这样它只会被调用一次。

有什么意见吗?

【讨论】:

  • 感谢分享。不要忘记接受答案。
猜你喜欢
  • 1970-01-01
  • 2018-01-05
  • 2017-02-12
  • 2013-04-15
  • 1970-01-01
  • 1970-01-01
  • 2017-04-25
  • 1970-01-01
  • 2017-07-16
相关资源
最近更新 更多