C# 如何从模式堆栈中删除特定页面?

C# 如何从模式堆栈中删除特定页面?,c#,xamarin.forms,C#,Xamarin.forms,我有四页,第一页到第二页到第三页到第四页。我使用推模式异步来向前导航。当我在第4页点击按钮时,它将导航到第2页。但点击第2页中的后退按钮会显示堆栈页面的所有历史记录。因此,如何从模式堆栈中删除页面。我还使用了navigation.Remove(页面),但它引发了一个异常。请导游 foreach (var page in Navigation.ModalStack) { if (page is Page3) { await PopModalPage(); }

我有四页,第一页到第二页到第三页到第四页。我使用推模式异步来向前导航。当我在第4页点击按钮时,它将导航到第2页。但点击第2页中的后退按钮会显示堆栈页面的所有历史记录。因此,如何从模式堆栈中删除页面。我还使用了navigation.Remove(页面),但它引发了一个异常。请导游

foreach (var page in Navigation.ModalStack)
{
    if (page is Page3)
    {
        await PopModalPage();
    }
}

foreach (var page in Navigation.ModalStack)
{
    if (page is Page4)
    {
        await PopModalPage();
    }
}
要从第4页导航到第2页,我使用以下代码
除此之外的任何优化方法???

请使用
等待导航.PopModalAsync()
并通读以获取有关
modalpage
的信息

编辑:

尚未对其进行测试,但有助于理解该方法:


for (var i = Navigation.NavigationStack.Count - 1; i > 0; i--)
{
    if (Navigation.NavigationStack[i] is Page2)
    {
        return;
    }
    await Navigation.PopModalAsync();
}

RemovePage
仅支持从
NavigationStack
中删除指定页面

如下所示:
Navigation.RemovePage(Navigation.NavigationStack[Navigation.NavigationStack.Count-1])

有关更多详细信息,请参阅:

如果您想返回2页,这将起作用

        Navigation.RemovePage(Navigation.NavigationStack[Navigation.NavigationStack.Count - 2]);
        Navigation.RemovePage(this);

首先,我们删除当前页面之前的页面,然后删除当前页面。

您可以使用以下帮助程序功能

/// <summary>
/// Class with extension methods for INavigation interface to help working with the modal page stack
/// </summary>
public static class ModalHelper
{
    /// <summary>
    /// Unwinds the modal stack of the navigation until reaching a page with the given type
    /// </summary>
    /// <typeparam name="PageType"></typeparam>
    /// <param name="navigation">The navigation object of the current top page</param>
    /// <returns></returns>
    public async static Task UnwindModalStackTo<PageType>(this INavigation navigation) where PageType : Page
    {
        await navigation.UnwindModalStackTo(p => p is PageType);
    }

    /// <summary>
    /// Unwinds the modal stack of the navigation until reaching the given page 
    /// </summary>
    /// <param name="navigation">The navigation object of the current top page</param>
    /// <param name="page">The page where to stop unwinding the modal stack</param>
    public async static Task UnwindModalStackTo(this INavigation navigation, Page page) 
    {
        await navigation.UnwindModalStackTo(p => p == page);
    }

    /// <summary>
    /// Unwinds the modal stack of the navigation until reaching a page that fulfils the predicate
    /// </summary>
    /// <param name="navigation">The navigation object of the current top page</param>
    /// <param name="predicate">A function which tests whether to stop at a given page</param>
    public async static Task UnwindModalStackTo(this INavigation navigation, Func<Page, bool> predicate)
    {
        bool found = false;

        while (navigation != null && navigation.ModalStack.Count > 0)
        {
            // Get the current top page of the modal stack
            Page topPage = navigation.ModalStack[navigation.ModalStack.Count - 1];

            // Get the second page in the modal stack from the top (This one will become top next after we pop)
            Page parentPage;
            if (navigation.ModalStack.Count > 1)
            {
                parentPage = navigation.ModalStack[navigation.ModalStack.Count - 2];
            }
            else
            {
                parentPage = null;
            }

            // When the top page fulfills the predicate, stop
            if (predicate(topPage))
            {
                found = true;
                break;
            }

            // Pop the top page
            await navigation.PopModalAsync();

            // We need to use the navigation of the new top page from here on
            navigation = parentPage?.Navigation;
        }

        // When the target page was not found, throw an exception
        if (!found)
        {
            throw new Exception("Desired page not found in modal stack");
        }
    }

}
在第1页:

private async void Button_Clicked(object sender, EventArgs e)
{
    Page p = new Page2();
    await Navigation.PushModalAsync(p);
}
等等

现在在第4页(为了返回第2页),我们使用以下代码关闭所有打开的模式页面,直到到达第2页

private async void Button_Clicked(object sender, EventArgs e)
{
    await Navigation.UnwindModalStackTo<Page2>();
}
private async void按钮\u已单击(对象发送方,事件参数e)
{
等待导航。UnwindModalStackTo();
}

请提供问题编辑@nineberry的可能副本。从第4页导航到第2页后,如何从堆栈中删除当前页面的可能副本。视图中不应显示两页(第4页和第3页)。PopModalAsync()此选项用于从堆栈中删除页面。如何一次单击删除多个页面。我需要删除第4页和第3页。我在第4页单击按钮时调用了两次PopModalPage()方法。问题解决了。但这是优化的方式吗?@Tester,这一点都不好。这是不灵活的,如果您必须在第3页和第4页之间添加页面,该怎么办?最好使用
PopToRootAsync
并从根页面转到特定页面,或者更改您的方法。PopToRootAsync导航到第1页,但我需要转到第2页。使用popto-root Async时,我会收到此异常。示例:System.InvalidoOperationException:PopToRootAsync在Android上不受全局支持,请使用NavigationPage。@Tester作为替代方法,您可以从
NavigationStack
中获取最后一个
页面
,并将其类型与第2页进行比较,然后弹出
页面
,直到获得所需的
页面
。如何从堆栈中删除当前页面???@Tester Navigation.RemovePage(此);谢谢让我试试这对我很有效。你仍然可以看到模态被弹出动画和所有。。。但我认为这是这里很多帖子中唯一值得回应的。
private async void Button_Clicked(object sender, EventArgs e)
{
    await Navigation.UnwindModalStackTo<Page2>();
}