如何在.NET MAUI Shell侧边栏中实现可折叠菜单项?
如何在.NET MAUI Shell侧边栏实现带子选项的可折叠菜单项
可以实现该效果,原生.NET MAUI Shell的FlyoutItem不支持直接折叠子项,你可以通过自定义控件来构建符合需求的侧边栏菜单,以下是具体实现方案:
1. 创建自定义可折叠菜单项控件
先定义一个包含展开/折叠逻辑的自定义ContentView,用来承载父项标题和子项列表:
XAML代码(CollapsibleFlyoutItem.xaml)
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="YourAppNamespace.Controls.CollapsibleFlyoutItem"> <VerticalStackLayout Spacing="2"> <!-- 父项标题按钮(点击切换展开/折叠) --> <Button Text="{Binding Title}" Command="{Binding ToggleExpandCommand}" HorizontalOptions="Fill" BackgroundColor="Transparent" Padding="10,8"/> <!-- 子项容器:根据IsExpanded控制显示/隐藏 --> <VerticalStackLayout x:Name="ChildContainer" IsVisible="{Binding IsExpanded}" Margin="20,0,0,0" Spacing="2"> <CollectionView ItemsSource="{Binding ChildItems}" VerticalOptions="FillAndExpand"> <CollectionView.ItemTemplate> <DataTemplate> <Button Text="{Binding Text}" Command="{Binding Command}" HorizontalOptions="Fill" BackgroundColor="Transparent" Padding="10,6"/> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> </VerticalStackLayout> </VerticalStackLayout> </ContentView>
C#后台代码(CollapsibleFlyoutItem.xaml.cs)
using System.Collections.ObjectModel; using System.ComponentModel; using System.Windows.Input; namespace YourAppNamespace.Controls; public partial class CollapsibleFlyoutItem : ContentView, INotifyPropertyChanged { // 绑定属性:父项标题 public static readonly BindableProperty TitleProperty = BindableProperty.Create(nameof(Title), typeof(string), typeof(CollapsibleFlyoutItem), string.Empty); // 绑定属性:子项列表 public static readonly BindableProperty ChildItemsProperty = BindableProperty.Create(nameof(ChildItems), typeof(ObservableCollection<FlyoutChildItem>), typeof(CollapsibleFlyoutItem), new ObservableCollection<FlyoutChildItem>()); // 绑定属性:是否展开 public static readonly BindableProperty IsExpandedProperty = BindableProperty.Create(nameof(IsExpanded), typeof(bool), typeof(CollapsibleFlyoutItem), false); public string Title { get => (string)GetValue(TitleProperty); set => SetValue(TitleProperty, value); } public ObservableCollection<FlyoutChildItem> ChildItems { get => (ObservableCollection<FlyoutChildItem>)GetValue(ChildItemsProperty); set => SetValue(ChildItemsProperty, value); } public bool IsExpanded { get => (bool)GetValue(IsExpandedProperty); set { SetValue(IsExpandedProperty, value); OnPropertyChanged(nameof(IsExpanded)); } } // 切换展开/折叠的命令 public ICommand ToggleExpandCommand { get; } public CollapsibleFlyoutItem() { InitializeComponent(); ToggleExpandCommand = new Command(ToggleExpandState); BindingContext = this; } private void ToggleExpandState() { IsExpanded = !IsExpanded; } } // 子项数据模型 public class FlyoutChildItem { public string Text { get; set; } public ICommand Command { get; set; } }
2. 在Shell中使用自定义控件
替换原生Shell.FlyoutContent,将自定义控件加入侧边栏布局:
<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:controls="clr-namespace:YourAppNamespace.Controls" x:Class="YourAppNamespace.AppShell"> <!-- 自定义侧边栏内容 --> <Shell.FlyoutContent> <VerticalStackLayout Padding="10" Spacing="8" BackgroundColor="{StaticResource BackgroundColor}"> <!-- 普通菜单项 --> <Button Text="首页" Command="{Binding NavigateToHomeCommand}" HorizontalOptions="Fill"/> <!-- 可折叠菜单项:设置 --> <controls:CollapsibleFlyoutItem Title="设置"> <controls:CollapsibleFlyoutItem.ChildItems> <controls:FlyoutChildItem Text="账户管理" Command="{Binding NavigateToAccountCommand}"/> <controls:FlyoutChildItem Text="通知设置" Command="{Binding NavigateToNotificationsCommand}"/> </controls:CollapsibleFlyoutItem.ChildItems> </controls:CollapsibleFlyoutItem> <!-- 可折叠菜单项:帮助中心 --> <controls:CollapsibleFlyoutItem Title="帮助中心"> <controls:CollapsibleFlyoutItem.ChildItems> <controls:FlyoutChildItem Text="使用指南" Command="{Binding NavigateToGuideCommand}"/> <controls:FlyoutChildItem Text="联系客服" Command="{Binding NavigateToSupportCommand}"/> </controls:CollapsibleFlyoutItem.ChildItems> </controls:CollapsibleFlyoutItem> </VerticalStackLayout> </Shell.FlyoutContent> <!-- 页面路由配置 --> <ShellContent Route="Home" ContentTemplate="{DataTemplate local:HomePage}"/> <!-- 其他页面路由... --> </Shell>
3. 自定义样式优化
你可以根据需求调整控件样式:
- 替换父项按钮为
Label+箭头图标,实现更直观的展开/折叠视觉提示 - 调整子项的缩进、字体大小、颜色等样式,匹配你的UI设计
- 添加动画效果,让展开/折叠过程更平滑
内容的提问来源于stack exchange,提问作者Francisco José Goñi
相关产品推荐
相关产品推荐

