如何在MAUI的Flyout菜单中添加Search Bar
在MAUI的Flyout菜单中添加Search Bar的具体方法
你可以通过自定义Flyout头部模板结合搜索逻辑实现需求,以下是两种常见实现方式:
方式一:静态菜单直接过滤显示/隐藏
1. 修改AppShell.xaml,添加带SearchBar的Flyout头部
将原Shell代码修改为如下结构,通过Shell.FlyoutHeaderTemplate定义包含搜索栏的Flyout头部:
<?xml version="1.0" encoding="UTF-8" ?> <Shell x:Class="AGROWORKS.MOBILE.AppShell" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:AGROWORKS.MOBILE" Shell.FlyoutBehavior="Flyout"> <!-- 自定义Flyout头部,包含搜索栏 --> <Shell.FlyoutHeaderTemplate> <DataTemplate> <StackLayout Padding="10" BackgroundColor="#f0f0f0"> <SearchBar Placeholder="Parsel ya da Kişi Arayın" TextChanged="SearchBar_TextChanged" Margin="0,10,0,0"/> </StackLayout> </DataTemplate> </Shell.FlyoutHeaderTemplate> <!-- 定义Flyout菜单项 --> <FlyoutItem Title="Ana Sayfa"> <ShellContent ContentTemplate="{DataTemplate local:MainPage}" Route="MainPage" /> </FlyoutItem> <!-- 可添加更多菜单项示例 --> <FlyoutItem Title="İstatistikler"> <ShellContent ContentTemplate="{DataTemplate local:StatsPage}" /> </FlyoutItem> </Shell>
2. 在后台代码实现搜索过滤逻辑
打开AppShell.xaml.cs,添加SearchBar_TextChanged事件处理方法,根据搜索文本控制菜单项的显示状态:
namespace AGROWORKS.MOBILE; public partial class AppShell : Shell { public AppShell() { InitializeComponent(); } private void SearchBar_TextChanged(object sender, TextChangedEventArgs e) { var searchText = e.NewTextValue?.ToLower() ?? string.Empty; // 遍历所有Flyout菜单项,匹配搜索文本后显示/隐藏 foreach (var item in FlyoutItems) { if (item is FlyoutItem flyoutItem) { flyoutItem.IsVisible = string.IsNullOrEmpty(searchText) || flyoutItem.Title.ToLower().Contains(searchText); } } } }
方式二:绑定ViewModel集合实现过滤(更适合动态菜单)
如果你的菜单是动态生成的,推荐使用ViewModel绑定集合的方式:
1. 创建菜单项ViewModel
namespace AGROWORKS.MOBILE; public class FlyoutMenuItemViewModel { public string Title { get; set; } public Type TargetPage { get; set; } }
2. 创建AppShell的ViewModel
using System.Collections.ObjectModel; using System.Linq; using Microsoft.Maui.Controls; namespace AGROWORKS.MOBILE; public class AppShellViewModel { public ObservableCollection<FlyoutMenuItemViewModel> MenuItems { get; set; } private List<FlyoutMenuItemViewModel> OriginalMenuItems { get; set; } private string _searchText; public string SearchText { get => _searchText; set { _searchText = value; FilterMenuItems(); } } public AppShellViewModel() { // 初始化原始菜单集合 OriginalMenuItems = new List<FlyoutMenuItemViewModel> { new FlyoutMenuItemViewModel { Title = "Ana Sayfa", TargetPage = typeof(MainPage) }, new FlyoutMenuItemViewModel { Title = "İstatistikler", TargetPage = typeof(StatsPage) } }; MenuItems = new ObservableCollection<FlyoutMenuItemViewModel>(OriginalMenuItems); } private void FilterMenuItems() { var filtered = string.IsNullOrEmpty(SearchText) ? OriginalMenuItems : OriginalMenuItems.Where(item => item.Title.ToLower().Contains(SearchText.ToLower())).ToList(); MenuItems.Clear(); foreach (var item in filtered) { MenuItems.Add(item); } } }
3. 修改AppShell.xaml绑定数据
<?xml version="1.0" encoding="UTF-8" ?> <Shell x:Class="AGROWORKS.MOBILE.AppShell" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:AGROWORKS.MOBILE" Shell.FlyoutBehavior="Flyout"> <!-- 设置BindingContext --> <Shell.BindingContext> <local:AppShellViewModel /> </Shell.BindingContext> <!-- 自定义Flyout头部 --> <Shell.FlyoutHeaderTemplate> <DataTemplate> <StackLayout Padding="10" BackgroundColor="#f0f0f0"> <SearchBar Placeholder="Parsel ya da Kişi Arayın" Text="{Binding SearchText, Mode=TwoWay}" Margin="0,10,0,0"/> </StackLayout> </DataTemplate> </Shell.FlyoutHeaderTemplate> <!-- 绑定动态菜单 --> <Shell.ItemTemplate> <DataTemplate> <Label Text="{Binding Title}" Margin="20,10,0,10" /> </DataTemplate> </Shell.ItemTemplate> <FlyoutItem ItemsSource="{Binding MenuItems}"> <ShellContent ContentTemplate="{DataTemplate local:MainPage}" /> </FlyoutItem> </Shell>
4. 添加页面跳转逻辑(可选)
在AppShell构造函数中注册路由,处理菜单点击跳转:
public AppShell() { InitializeComponent(); // 注册页面路由 Routing.RegisterRoute(nameof(MainPage), typeof(MainPage)); Routing.RegisterRoute(nameof(StatsPage), typeof(StatsPage)); // 处理菜单项点击 ItemSelected += async (sender, e) => { if (e.SelectedItem is FlyoutMenuItemViewModel item) { await Shell.Current.GoToAsync($"//{item.TargetPage.Name}"); FlyoutIsPresented = false; } }; }
内容的提问来源于stack exchange,提问作者Ahmet Gökhan Aktaş
相关产品推荐
相关产品推荐

