1

我在如何实现导航到未在 shell 视觉层次结构中表示的页面(在我的 Shell xaml 中定义)时遇到问题。

根据我在 docs 中读到的有关 Shell 导航的内容,我可以通过两种方式导航到这样的页面:

  1. 使用导航属性:
    Navigation.PushAsync(new TargetPage());
    
  2. 注册路由并使用 Shell 的 URI 导航:
    Routing.RegisterRoute("targetPageRoute", typeof(TargetPage));
    
    Shell.Current.GoToAsync("targetPageRoute");
    

两种方法都遇到相同的问题:一旦您使用任何一种方法导航到视觉层次结构之外的页面,Shell 的 flyoutItems 之间的正常导航(使用弹出菜单)将使应用程序崩溃并出现以下错误:

System.Collections.Generic.KeyNotFoundException: The given key 'MyProject.TargetPage' was not present in the dictionary.

如何重现:

  1. 向 Shell 的视觉层次结构添加两项:

    <FlyoutItem Title="page 1">
        <Tab>
            <ShellContent>
                <local:Page1 />
            </ShellContent>
        </Tab>
    </FlyoutItem>
    
    <FlyoutItem Title="page 2">
        <Tab>
            <ShellContent>
                <local:Page2 />
            </ShellContent>
        </Tab>
    </FlyoutItem>
    
  2. 使用本文顶部描述的两种导航方式之一,使用 Page1 上的按钮导航到 Page3(上面未定义的页面):
    private void Button_Clicked(object sender, EventArgs e) {
        Navigation.PushAsync(new Page3());
    }
    
  3. 使用弹出菜单导航到第 2 页
  4. 使用弹出菜单导航到 Page1 - 应用程序现在应该崩溃。

我已经在我的主要项目和一个小型测试项目中对此进行了广泛的测试,但似乎找不到解决方案。任何帮助将不胜感激。

4

3 回答 3

1

这是来自 xamarin 表单的 github 的相同问题:https ://github.com/xamarin/Xamarin.Forms/issues/6738 此外,如果您向下滚动,您会看到 pull request,它实际上解决了问题(已经帮助我们公司的应用程序)。您必须实现一个自定义渲染器,该渲染器将从 ShellItemRenderer 继承,并覆盖现有的 HandleFragmentUpdate(因为它使用原始 ShellItemRendererBase 中的私有字段,您也必须在此处重新设置它们(而不是覆盖,只需从当前 xamarin android ShellItemRendererBase.cs 文件中复制它们))。但是,正如官方文档所建议的那样,您不应只将此渲染器分配给 ShellItem 派生类,而是必须创建自定义 ShellRenderer 并覆盖它的 CreateShellItemRenderer 方法(因此它将创建您的固定外壳项目渲染器而不是默认的渲染器)。

当然,您现在所做的一切都是暂时的,直到 xamarin 推出包含此修复程序的新更新...

于 2019-07-03T16:52:36.810 回答
1

您可以尝试像这样更改 shell.xaml:

<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
    <Tab Title="page 1">
        <ShellContent  >
            <local:Page1 />
        </ShellContent>
    </Tab>
    <Tab Title="page 2">
        <ShellContent   >
            <local:Page2 />
        </ShellContent>
    </Tab>
</FlyoutItem>
于 2019-07-01T08:50:59.663 回答
0

您是否尝试在设置之前添加您的路线BindingContext?例如 :

public NavigationShell()
{
   Routing.RegisterRoute("targetPageRoute", typeof(TargetPage));
   BindingContext = this;
}
于 2019-07-01T09:09:46.127 回答