You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin.Forms:禁用FlyoutItem并修改默认启动页面问题求助

Xamarin.Forms Shell 默认页切换问题解决

问题背景

项目中使用Xamarin.Forms Shell,包含多个FlyoutItem:

  • Page1默认禁用,仅满足特定条件时启用
  • 需求:当Page1禁用时,默认显示Page2而非Page1
  • 尝试直接设置this.CurrentItem = Page2后,后续使用GoToAsync("..")返回时触发路由歧义错误:

    System.ArgumentException: 'Ambiguous routes matched for:
    //D_FAULT_FlyoutItem7/IMPL_Page2/Page2/Page1 matches found:
    //D_FAULT_FlyoutItem7/IMPL_Page2/Page2/Page1,
    //D_FAULT_FlyoutItem7/IMPL_Page2/Page2/Page1 Parameter name: uri'

现有代码

MyShell.xaml

<FlyoutItem x:Name="Page1" IsEnabled="False" Title="xxxx xxxx" StyleClass="MenuItemLayoutStyle" >
    <ShellContent Route="Page1">
        <local:Page1 Parameter="-1" />
    </ShellContent>
</FlyoutItem>
<FlyoutItem x:Name="Page2" Title="Alle Reisen" Icon="icon_feed.png">
    <ShellContent Route="Page2" ContentTemplate="{DataTemplate local:Page2}" />
</FlyoutItem>
<FlyoutItem Title="About" Icon="icon_about.png">
    <ShellContent Route="AboutPage" ContentTemplate="{DataTemplate local:AboutPage}" />
</FlyoutItem>

MyShell.xaml.cs

public partial class MyShell : Xamarin.Forms.Shell
{
    public MyShell()
    {
        InitializeComponent();

        Routing.RegisterRoute(nameof(Page2), typeof(Page2));
        Routing.RegisterRoute(nameof(Page1), typeof(Page1));

        this.Page1.IsEnabled = <Some Condition>;
    }
}

解决方案

1. 动态调整FlyoutItem顺序(推荐)

通过修改FlyoutItems集合的顺序,把需要默认显示的Page2移到第一位,Shell会自动加载第一个FlyoutItem,无需手动设置CurrentItem,从根源避免路由冲突。

修改后台代码:

public MyShell()
{
    InitializeComponent();

    // 注意:如果XAML中已设置ShellContent的Route属性,可删除下面两行重复注册
    // Routing.RegisterRoute(nameof(Page2), typeof(Page2));
    // Routing.RegisterRoute(nameof(Page1), typeof(Page1));

    bool enablePage1 = <Some Condition>;
    Page1.IsEnabled = enablePage1;

    if (!enablePage1)
    {
        // 将Page2移至FlyoutItems的首位
        var flyoutList = FlyoutItems.ToList();
        flyoutList.Remove(Page2);
        flyoutList.Insert(0, Page2);
        
        FlyoutItems.Clear();
        foreach (var item in flyoutList)
        {
            FlyoutItems.Add(item);
        }
    }
}

2. 移除重复的路由注册

FlyoutItem下的ShellContent已经通过Route属性定义了路由,后台重复调用Routing.RegisterRoute会导致路由重复,引发歧义。直接删除后台的路由注册代码即可。

3. 修复CurrentItem设置的路由栈问题(备选)

如果必须手动设置CurrentItem,在设置后清理导航栈,确保路由栈只有当前页面:

public MyShell()
{
    InitializeComponent();

    // 移除重复路由注册
    // Routing.RegisterRoute(nameof(Page2), typeof(Page2));
    // Routing.RegisterRoute(nameof(Page1), typeof(Page1));

    bool enablePage1 = <Some Condition>;
    Page1.IsEnabled = enablePage1;

    if (!enablePage1)
    {
        CurrentItem = Page2;
        // 清理导航栈到根节点
        _ = Navigation.PopToRootAsync();
    }
}

内容的提问来源于stack exchange,提问作者Bernd Morgeneyer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 12:43:15