Xamarin.Forms Shell 视觉层次之外的导航
Xamarin.Forms Shell navigation outside the visual hierarchy
我遇到了如何导航到 shell 视觉层次结构(在我的 Shell xaml 中定义)中未表示的页面的问题。
根据我对 Shell 导航 in the docs 的了解,我可以通过两种方式导航到这样的页面:
- 使用导航属性:
Navigation.PushAsync(new TargetPage());
- 注册路线并使用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.
如何重现:
向 Shell 的视觉层次添加两个项目:
<FlyoutItem Title="page 1">
<Tab>
<ShellContent>
<local:Page1 />
</ShellContent>
</Tab>
</FlyoutItem>
<FlyoutItem Title="page 2">
<Tab>
<ShellContent>
<local:Page2 />
</ShellContent>
</Tab>
</FlyoutItem>
- 使用第 1 页上的按钮导航到第 3 页(上面未定义的页面),使用本 post 顶部描述的两种导航方式之一:
private void Button_Clicked(object sender, EventArgs e) {
Navigation.PushAsync(new Page3());
}
- 使用弹出菜单导航至第 2 页
- 使用弹出菜单导航至第 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>
您是否尝试过在设置 BindingContext
之前添加您的路线?
例如:
public NavigationShell()
{
Routing.RegisterRoute("targetPageRoute", typeof(TargetPage));
BindingContext = this;
}
这是来自 xamarin forms 的相同问题 github:https://github.com/xamarin/Xamarin.Forms/issues/6738
另外,如果你向下滚动,你会看到 pull request,这实际上解决了问题(已经帮助我们公司的应用程序)。
您必须实现一个自定义渲染器,它将继承自 ShellItemRenderer,并覆盖现有的 HandleFragmentUpdate(因为事实上,它使用原始 ShellItemRendererBase 中的私有字段,您也必须在此处对它们进行变基(不是覆盖,只需从当前的 xamarin android ShellItemRendererBase.cs 文件中复制它们))。
但是,正如官方文档所建议的那样,您不应只将此渲染器分配给 ShellItem 派生,相反,您必须创建自定义 ShellRenderer 并覆盖它的 CreateShellItemRenderer 方法(因此它会创建固定的 shell 项目渲染器默认的)。您只需将此渲染器应用于 xamarin 表单中的自定义 shell 控件。
当然,您现在所做的一切都是暂时的,直到 xamarin 推送包含此修复程序的新更新...
我遇到了如何导航到 shell 视觉层次结构(在我的 Shell xaml 中定义)中未表示的页面的问题。
根据我对 Shell 导航 in the docs 的了解,我可以通过两种方式导航到这样的页面:
- 使用导航属性:
Navigation.PushAsync(new TargetPage());
- 注册路线并使用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.
如何重现:
向 Shell 的视觉层次添加两个项目:
<FlyoutItem Title="page 1"> <Tab> <ShellContent> <local:Page1 /> </ShellContent> </Tab> </FlyoutItem> <FlyoutItem Title="page 2"> <Tab> <ShellContent> <local:Page2 /> </ShellContent> </Tab> </FlyoutItem>
- 使用第 1 页上的按钮导航到第 3 页(上面未定义的页面),使用本 post 顶部描述的两种导航方式之一:
private void Button_Clicked(object sender, EventArgs e) { Navigation.PushAsync(new Page3()); }
- 使用弹出菜单导航至第 2 页
- 使用弹出菜单导航至第 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>
您是否尝试过在设置 BindingContext
之前添加您的路线?
例如:
public NavigationShell()
{
Routing.RegisterRoute("targetPageRoute", typeof(TargetPage));
BindingContext = this;
}
这是来自 xamarin forms 的相同问题 github:https://github.com/xamarin/Xamarin.Forms/issues/6738 另外,如果你向下滚动,你会看到 pull request,这实际上解决了问题(已经帮助我们公司的应用程序)。 您必须实现一个自定义渲染器,它将继承自 ShellItemRenderer,并覆盖现有的 HandleFragmentUpdate(因为事实上,它使用原始 ShellItemRendererBase 中的私有字段,您也必须在此处对它们进行变基(不是覆盖,只需从当前的 xamarin android ShellItemRendererBase.cs 文件中复制它们))。 但是,正如官方文档所建议的那样,您不应只将此渲染器分配给 ShellItem 派生,相反,您必须创建自定义 ShellRenderer 并覆盖它的 CreateShellItemRenderer 方法(因此它会创建固定的 shell 项目渲染器默认的)。您只需将此渲染器应用于 xamarin 表单中的自定义 shell 控件。
当然,您现在所做的一切都是暂时的,直到 xamarin 推送包含此修复程序的新更新...