首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >PopAsync不起作用

PopAsync不起作用
EN

Stack Overflow用户
提问于 2020-01-06 19:44:29
回答 2查看 2.2K关注 0票数 0

我正在用Xamarin.Forms开发一个应用程序,直到我遇到了一个导航错误,事情一直很稳定。让我困惑的是,我已经成功地在其他页面上使用了相同的代码调用,但是突然之间,这个页面就不能工作了。

我设计了一个独特的导航流,因为我正在尝试实现可视化结果,使用一个主细节的组合,使用普通的push / pop代码实现两层导航页面。我听从了本文是关于medium.com的的建议。

该应用程序初始化一个名为“根导航”的主页,该主页初始化主页面和详细页。

代码语言:javascript
代码运行次数:0
运行
复制
public App()
{
    InitializeComponent();

    MainPage = new RootNavigation();
}

根导航页面:

代码语言:javascript
代码运行次数:0
运行
复制
public partial class RootNavigation : MasterDetailPage
{
    private MenuPage menuPage;
    private NavigationPage OuterPage;
    private NavigationPage InnerPage;

    public RootNavigation()
    {
        this.Master = this.menuPage = new MenuPage();
        this.menuPage.MenuItemsListView.ItemSelected += Menu_ItemSelected;

        var viewModel = new SelectEmployeeViewModel();
        var page = new SelectEmployeePage(viewModel);
        SetAsDetailPage(page);
    }

为了在应用程序中向前导航,我使用了一种名为“设置为详细信息页”的方法,该方法可以弥合主细节行为和导航推送/弹出行为之间的差距。

代码语言:javascript
代码运行次数:0
运行
复制
private void SetAsDetailPage(ContentPage page)
{
    NavigationPage.SetHasNavigationBar(newPage, false);
    if (newPage.GetType() == typeof(JobDetailPage))
    {
        newPage.ToolbarItems.Add(
            new ToolbarItem()
            {
                Text = "Back",
                Command = new Command(() => BackButton_Clicked())
            });
    }
    this.InnerPage = this.InnerPage ?? new NavigationPage();
    this.InnerPage.Navigation.PushAsync(page);
    this.OuterPage = this.OuterPage ?? new NavigationPage(this.InnerPage);
    this.Detail = this.Detail ?? this.OuterPage;
}

然后,向后导航调用两个方法中的一个:"BackButton_Clicked()“或"ReturnToJobList()”。

代码语言:javascript
代码运行次数:0
运行
复制
private void ReturnToJobList()
{
    while (InnerPage.CurrentPage.GetType() != typeof(JobsPage))
    {
        var current = InnerPage.CurrentPage.ToString();
        System.Diagnostics.Debug.WriteLine($"'{current}' attempting Navigation.Pop()");
        InnerPage.PopAsync();
    }
}

private void BackButton_Clicked()
{
    this.InnerPage.PopAsync();
}

显示只读数据的所有页面都已无问题地导航。当我完成页面时,我让它调用MessagingCenter,根导航接收消息并执行所需的导航。例如,"MenuPage_ItemSelected“事件处理程序触发代码:

代码语言:javascript
代码运行次数:0
运行
复制
if (e.SelectedItem.ToString().ToLower() == "log out")
{
    Device.InvokeOnMainThreadAsync(() =>
    {
        InnerPage.PopToRootAsync();
        this.IsPresented = false;
    });
}

这似乎很好,在我花了一段时间研究了一下,当第二个页面在后台线程上调用'pop to root‘时,我必须在主线程上调用它。

好的,最后到问题页面:“更新作业说明”页面。该页面引发对消息传递中心的调用,根导航页将获取该调用并执行以下代码:

代码语言:javascript
代码运行次数:0
运行
复制
private async void SaveJobNotes(ContentPage sender)
{
    if (sender is UpdateJobNotesPage notesPage)
    {
        bool result = await SaveNewJobNote(notesPage);
        var message = result ? "Saved changes" : "An error occurred; changes not saved";
        await DisplayAlert("Save", message, "OK");
    }

    ReturnToJobList();
}

通过遍历代码,它正确地执行SaveNewJobNote()并返回true。然后,它等待显示警报“保存的更改”。然后,代码被卡在"ReturnToJobList()“中的无限while循环中,永远打印到调试输出[0:] 'Application.Views.UpdateJobNotesPage' attempting Navigation.Pop()中。在经历了大约一百万次的循环之后,我厌倦了等待并退出调试器。我似乎不能做任何事情来使这一页消失!

我尝试了一堆研究PopAsyncPopModalAsync之间的区别的东西。在检查了所讨论的不同页面的导航堆栈之后,一切看起来都和我所期望的完全一样--任何东西都没有模态堆栈(因为我从来没有在任何东西上调用过PushModalAsync ),RootNavigation堆栈上有0,OuterPage堆栈上有1,InnerPage堆栈上有4。这一切对我来说都是非常有意义的,但它仍然没有弹出“更新职务说明”页面。我也尝试过用Navigation.RemovePage(page)编写代码,但没有成功。唯一的区别是调试器包括打印关于我的代码的警告并建议我使用PopAsync()

我还尝试了一些不同的方法,从this.Navigationthis.Outerthis.Outer.Navigationthis.Innerthis.Inner.Navigation中调用,但都没有成功。

我已经看过关于堆栈溢出的许多其他问题,包括这个问题这个问题,但在这种情况下似乎都不适用。如有任何协助,将不胜感激!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-08 20:40:40

在“职务列表”页面可见之前,我还没有真正弄清楚我创建的应该调用InnerNavigation.PopAsync()的代码块的问题所在。看起来,代码块中的所有变量都可以计算出我所期望的值,但不知怎么的,它似乎无法从堆栈中弹出任何内容。

但是,我确实更改了处理保存作业备注的代码块,它现在会弹出堆栈中的页面。

代码语言:javascript
代码运行次数:0
运行
复制
private async void SaveJobNotes(ContentPage sender)
{
    this.InnerPage.PopAsync(); //I don't understand why this works and the 
                                //other didn't, but it correctly pops the page

    if (sender is UpdateJobNotesPage notesPage)
    {
        bool noteSaved = await SaveNewJobNote(notesPage);
        bool progressSaved = await SaveJobProgress(notesPage);
        var message = noteSaved && progressSaved ? 
            "Changes were save successfully" : 
            "An error occurred; changes not saved";
        await DisplayAlert("Save", message, "OK");
    }
}
票数 1
EN

Stack Overflow用户

发布于 2020-01-06 20:22:58

我记得这事发生在我身上。我完全忘了是什么原因,但我也进行了一些古怪的导航。我的问题是弹出窗口,他们一度创建了一个新的堆栈。所以当我突然出现的时候,我得到了意想不到的结果。

我怀疑您也在某个地方创建另一个堆栈,特别是在调试器中处于0的情况下。

罪魁祸首很可能潜伏在InvokeOnMainThread()周围。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59618047

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档