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
相关产品推荐
相关产品推荐

