【问题标题】:PopAsync causes ArgumentOutOfRangeExceptionPopAsync 导致 ArgumentOutOfRangeException
【发布时间】:2023-04-08 09:26:01
【问题描述】:

我对@9​​87654322@ 还很陌生。我在出现的主页上有一个非常简单的功能

async public Task BaseAppearing()
    {
        if (UserID == null)
        {
            var page = new LoginPage();
            await App.Navigate(page);
        }
        else
        {
            stopWatch.Restart();
        }
    }

现在登录页面显示正常,问题是在登录页面中,当我点击登录并尝试弹出导航堆栈时,出现以下错误

未处理的异常:

System.ArgumentOutOfRangeException:索引超出范围。一定是 非负数且小于集合的大小。参数名称: 索引

应用崩溃了。

异常仅在 Android(模拟器和真实)中发生。在 UWP 中它工作得很好

弹出代码也很简单

public static Task PopNavigation()
    {
        var nav = Current.MainPage.Navigation;
        Task ret;
        try
        {
            ret = nav.PopAsync();
        }
        catch (Exception ex)
        {
            ex.Log();
            ret = Navigate(Current.MainPage);
        }
        return ret;
    }

它不仅抛出错误,而且永远不会到达异常处理程序。

另外,我了解到有时导航堆栈会损坏/空。但不,NavigationStack 有 2 项。 MainPage 和 LoginPage,我认为是正确的

所有导航都发生在同一个堆栈上,因为我在应用程序中只有 1 个导航功能,而这就是我为导航所调用的全部

请告知可以做什么

更新 我尝试将我的代码更改为使用NavigationPage,如下所示,但没有帮助(我也得到了顶部的 2 个标题栏)

public async static Task Navigate(Page Page)
    {
        //await Current.MainPage.Navigation.PushAsync( Page);
        await Current.MainPage.Navigation.PushAsync( new NavigationPage( Page));
    }

如果这可能对某人有所帮助,这是我的堆栈跟踪

在 System.Collections.Generic.List`1[T].get_Item (System.Int32 索引)[0x00009] 在 /Users/builder/jenkins/workspace/xamarin-android-d15-9/xamarin-android/external/mono/external/corefx/src/Common/src/CoreLib/System/Collections/Generic/List.cs:180 在 Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer.GetFragment (Xamarin.Forms.Page 页面,System.Boolean 已删除,System.Boolean popToRoot) [0x00003] 在 D:\a\1\s\Xamarin.Forms.Platform.Android\AppCompat\NavigationPageRenderer.cs:865 在 Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer.SwitchContentAsync (Xamarin.Forms.Page 页面、System.Boolean 动画、System.Boolean 已删除,System.Boolean popToRoot) [0x0001a] 在 D:\a\1\s\Xamarin.Forms.Platform.Android\AppCompat\NavigationPageRenderer.cs:768 在 Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer.OnPopViewAsync (Xamarin.Forms.Page 页面,System.Boolean 动画)[0x00017] in D:\a\1\s\Xamarin.Forms.Platform.Android\AppCompat\NavigationPageRenderer.cs:592 在 Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer.PopViewAsync (Xamarin.Forms.Page 页面,System.Boolean 动画)[0x00000] in D:\a\1\s\Xamarin.Forms.Platform.Android\AppCompat\NavigationPageRenderer.cs:154 在 Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer.OnPopped (System.Object 发送者, Xamarin.Forms.Internals.NavigationRequestedEventArgs e) [0x00000] 在 D:\a\1\s\Xamarin.Forms.Platform.Android\AppCompat\NavigationPageRenderer.cs:573 在 Xamarin.Forms.NavigationPage+d__69.MoveNext () [0x0004c] 在 D:\a\1\s\Xamarin.Forms.Core\NavigationPage.cs:297 --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 Xamarin.Forms.NavigationPage+d__68.MoveNext() [0x0004c] 在 D:\a\1\s\Xamarin.Forms.Core\NavigationPage.cs:280 --- 从先前引发异常的位置结束堆栈跟踪 --- 在 Xamarin.Forms.NavigationPage+d__45.MoveNext () [0x000cb] 在 D:\a\1\s\Xamarin.Forms.Core\NavigationPage.cs:168 --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 Qleeg.LoginPage+d__2.MoveNext () [0x003f8] 在 D:\Projects\Qleeg\Qleeg\Qleeg\Views\LoginPage.xaml.cs:70 --- 从先前抛出异常的位置结束堆栈跟踪 --- 在(包装器动态方法) System.Object.30(intptr,intptr) at (wrapper native-to-managed) System.Object.30(intptr,intptr)

我做错了什么?

更新 2

这是应用的构造函数

public App()
    {
        InitializeComponent();

        AppDomain.CurrentDomain.UnhandledException += (sender, args) => OnError(sender, args.ExceptionObject as Exception);
        TaskScheduler.UnobservedTaskException += (sender, args) => OnError(sender, args.Exception);
        MainPage = new NavigationPage(new MainPage());
   ......
}

这是我的导航代码

从主页面到登录页面

async public static Task BaseAppearing(this ContentPage Input)
{
    if (App.Current.UserID == null)
    {
        var page = new LoginPage();
        await Input.Navigation.PushAsync(page);
    }
    else
    {
        App.Current.stopWatch.Restart();
    }
}

回来

lblMessage.Text = "Welcome!";
lblMessage.TextColor = Color.Green;
Functions.WriteLog("Login", "pre nav pop");
//await App.PopNavigation();// App.Current.MainPage.Navigation.PopAsync();
await Navigation.PopAsync();//THIS IS LINE 70

更新 3

我将我的 MainPage 代码切换为:

    async private void MainPage_Appearing(object sender, EventArgs e)
    {
        if (App.Current.UserID == null) {await App.Current.MainPage.Navigation.PushAsync(new NavigationPage(new LoginPage ())); }
    }

现在,错误消失了(虽然我对原因感到困惑),但 Navigaion.PopAsync() 根本什么也没做。没有错误,但也没有导航。

此外,LoginPage 现在显示顶部有 2 个标题行/标题。

【问题讨论】:

  • 你在使用 NavigationPage 吗?
  • 嗨。如果我理解正确,那么我尝试了。但不,它没有帮助。请参阅帖子中的更新。谢谢!
  • 您是否在使用第三方插件进行导航?在此处查看如何在 xamarin.forms 中推送导航:navigation/hierarchical
  • 嗨。感谢您的参与。不。我没有使用任何第三方插件。是的,我读过那篇文章,而且我的代码似乎是正确的。此外,在UWP 中,它可以完美运行。 (我应该只使用整个系统的一个页面的导航,而不是每个单独的页面。对吗?)

标签: android xamarin.forms navigation


【解决方案1】:

如果您在 Android 上将页面推送到 OnAppearing,它将无法正确初始化,随后对 PopAsync 的调用或只是按工具栏中的后退按钮将导致此错误。要绕过,您必须引入一个延迟,以便主页可以首先正确初始化。

protected override void OnAppearing()
{ 
    base.OnAppearing();

    Task.Factory.StartNew(() => Thread.Sleep(500)).ContinueWith(async (t) =>
    {
        await Navigation.PushAsync(new MyNewPage(), false);
    }, TaskScheduler.FromCurrentSynchronizationContext());
}

【讨论】:

    【解决方案2】:

    添加

    Task.Delay(300)

    在导航页面之前。

    我知道这是一个 hack 但是如果您想在出现时导航到其他页面,那么我们必须这样做。 导致整个页面尚未初始化。 所以我们必须等待几秒钟才能在导航堆栈中正确初始化页面

    【讨论】:

      【解决方案3】:

      要将 NavigationPage 添加到您的根页面:

      public App ()
      {
        MainPage = new NavigationPage (new Page1Xaml ());
      }
      

      简单的推送页面:

      async void OnNextPageButtonClicked (object sender, EventArgs e)
      {
        await Navigation.PushAsync (new Page2Xaml ());
      }
      

      弹出一个页面:

      async void OnPreviousPageButtonClicked (object sender, EventArgs e)
      {
        await Navigation.PopAsync ();
      }
      

      弹出到根页面:

      async void OnRootPageButtonClicked (object sender, EventArgs e)
      {
        await Navigation.PopToRootAsync ();
      }
      

      使用我上面列出的代码在 xamarin.forms 中推送和弹出页面。我无法理解您项目中的 await App.Navigate(page); 是什么。

      我尝试如下更改我的代码以使用 NavigationPage,但没有 无济于事(我也得到了顶部的 2 个标题栏)

      您的项目中只需要一个 NavigationPage 实例。不要像这样推送到新的 NavigationPage:

      await Current.MainPage.Navigation.PushAsync( new NavigationPage( Page));
      

      只需推送到您想要的页面:

       await Current.MainPage.Navigation.PushAsync(Page);
      

      【讨论】:

      • 您好,感谢您的详细解释。但恐怕我正在按照书中的内容做任何事情。我似乎看不出我的代码和你的代码有什么不同。我已经在“更新 2”下的帖子末尾重新发布了我的 sn-ps。你能解释一下我的错误吗?再次感谢!
      • @YisroelM.Olewski 你的代码看起来不错。你能检查一下 LoginPage.xaml.cs:70 中的代码是什么,错误似乎发生在那里。如果您可以分享更多页面代码,我们可以更轻松地找出错误。
      • @YisroelM.Olewski 你能尝试使用 Current.MainPage.Navigation.PushAsync(new NavigationPage(Page));而不是使用 Input.Navigation.PushAsync(page);。删除输入。
      • 嗨。您的代码停止了错误抛出,但导航现在也不起作用。此外,我现在在第二页中有 2 个标题。有关完整结果,请参阅原始帖子中的更新 3。再次感谢您的关心。
      • @YisroelM.Olewski 1.直接推送到页面而不是推送到 NavigationPage:await App.Current.MainPage.Navigation.PushAsync(new LoginPage ());。 2. 试试Current.MainPage.Navigation.PopAsync ();
      猜你喜欢
      • 2010-11-04
      • 1970-01-01
      • 2011-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-11
      • 1970-01-01
      相关资源
      最近更新 更多