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

NET MAUI中如何通过ViewModel实现汉堡菜单(Flyout)?

MAUI Shell汉堡菜单(Flyout)不显示问题修复

问题原因分析

当前实现存在核心用法错误:

  • Shell.ItemTemplate用途误解:该模板用于定义单个Flyout菜单项的UI样式,而非承载整个菜单列表。你在模板中嵌套CollectionView的方式完全不符合Shell Flyout的设计逻辑。
  • 未正确绑定菜单数据源:Shell的Flyout菜单列表需通过ItemsSource属性绑定到FlyoutItems集合,而非在ItemTemplate中手动渲染列表。
  • FlyoutItem配置不完整:创建的FlyoutItem仅设置了Title,未关联路由或内容,即使菜单显示也无法实现导航功能。

修复步骤及代码修改

1. 调整ShellViewModel中的FlyoutItem配置

给每个FlyoutItem添加对应已注册的路由:

public partial class ShellViewModel : ObservableObject
{
    public List<FlyoutItem> FlyoutItems { get; private set; } = new List<FlyoutItem>();

    public ShellViewModel()
    {
        AddMenuItems();
    }

    private void AddMenuItems()
    {
        var flyoutItems = new List<FlyoutItem>
        {
            new FlyoutItem
            {
                Title = "首页",
                Route = PageRoutes.HomePage
            },
            new FlyoutItem
            {
                Title = "详情页",
                Route = PageRoutes.DetailsPage
            }
        };
        
        FlyoutItems.AddRange(flyoutItems);
    }
}

2. 修改AppShell的XAML代码

移除错误的CollectionView嵌套,通过ItemsSource绑定菜单数据源,并简化Shell.ItemTemplate为单个菜单项样式:

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    x:Class="MauiUI.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:MauiUI"
    xmlns:pages="clr-namespace:MauiUI.Pages"
    x:Name="shell"
    ItemsSource="{Binding FlyoutItems}">

    <Shell.ItemTemplate>
        <DataTemplate>
            <Grid Padding="15,10">
                <Label Text="{Binding Title}"
                       TextColor="White"
                       FontSize="18" />
            </Grid>
        </DataTemplate>
    </Shell.ItemTemplate>

    <ShellContent
        Title="排球女神"
        ContentTemplate="{DataTemplate pages:SplashPage}"
        Route="HomePage" />

</Shell>

3. 保留AppShell构造函数逻辑

原有的ViewModel注入和路由注册逻辑无需修改,确保绑定上下文正确即可:

public partial class AppShell : Shell
{
    private ShellViewModel viewModel => BindingContext as ShellViewModel;

    public AppShell(ShellViewModel viewModel)
    {
        BindingContext = viewModel;
        RegisterRoutes();
        InitializeComponent();
    }

    private void RegisterRoutes()
    {
        Routing.RegisterRoute(PageRoutes.LoginPage, typeof(LoginPage));
        Routing.RegisterRoute(PageRoutes.RegisterPage, typeof(RegisterPage));
        Routing.RegisterRoute(PageRoutes.HomePage, typeof(MainPage));
        Routing.RegisterRoute(PageRoutes.DetailsPage, typeof(PlayerDetailsPage));
        Routing.RegisterRoute(PageRoutes.AddOrUpdatePage, typeof(AddOrUpdatePlayer));
    }
}

额外说明

  • Shell会自动处理ItemsSource中FlyoutItem的渲染,无需手动管理列表控件。
  • 若需给Flyout菜单添加图标,可在FlyoutItem中设置Icon属性,例如Icon="home.png"。
  • 若要隐藏默认ShellContent在Flyout中的显示,可给该ShellContent设置FlyoutItemIsVisible="False"。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 11:21:02