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

MAUI切换Flyout Item后Search Handler消失问题求助

.NET MAUI Shell 自定义SearchHandler切换FlyoutItem后消失问题

问题场景

在Shell的首个FlyoutItem对应的PlatformPage中使用了自定义SearchHandler,存在多个FlyoutItem。执行以下操作后,主FlyoutItem的SearchHandler消失:

  • 从首个FlyoutItem导航至子页面
  • 从子页面跳转至其他FlyoutItem
  • 从该FlyoutItem返回首个FlyoutItem

已尝试切换FlyoutItem时清除导航栈,且验证过所有注册流程,需求是返回主FlyoutItem时SearchHandler能正常显示。

相关代码片段

自定义SearchHandler代码

<Shell.SearchHandler
    Placeholder="Enter search term"
    ShowsResults="true">
    <handlers:CustomSearchHandler x:Name="CustomSearchHandler " BindingContext="{Binding Source={x:Reference Name=MainPageViewModel}}"
        Placeholder="{Binding [SearchCustomCode], Source={x:Static util:Translator.Instance}}">
        <handlers:CustomSearchHandler.ItemTemplate>
            <DataTemplate x:DataType="models:CustomModel">
                <Label Margin="2,4" Text="{Binding Name}"></Label>
            </DataTemplate>
        </handlers:CustomSearchHandler .ItemTemplate>
    </handlers:CustomSearchHandler >
</Shell.SearchHandler>

Shell FlyoutItem代码

<FlyoutItem x:Name="MainPageTitle"
            Title="{Binding [MainPage], Source={x:Static util:Translator.Instance}}"
            Icon="menu_status.png">
    <ShellContent x:Name="MainShell"
                  Title="{Binding [MainPage], Source={x:Static util:Translator.Instance}}"
                  Icon="menu_status.png"
                  ContentTemplate="{DataTemplate views:PlatformPage}"
                  Route="MainPageRoute" />
</FlyoutItem>

<FlyoutItem Title="{Binding [SecondMenu], Source={x:Static util:Translator.Instance}}"
            Icon="sync.png">
    <ShellContent Route="sync"
                  ContentTemplate="{DataTemplate views:secondPage}"
                  IsVisible="{Binding CanGoOnline, Converter={StaticResource InvertedBoolConverter}}">
    </ShellContent>
</FlyoutItem>

主页面导航至子页面代码

var navigationParameter = new Dictionary<string, object>
{
    { "test", 123 }
};

await Shell.Current.GoToAsync("subPage", navigationParameter);        

解决方案

方案1:将SearchHandler绑定到对应ShellContent而非根Shell

把Shell.SearchHandler移到主FlyoutItem的ShellContent内部,确保每个ShellContent拥有独立的SearchHandler实例,避免切换时被覆盖或销毁:

<FlyoutItem x:Name="MainPageTitle"
            Title="{Binding [MainPage], Source={x:Static util:Translator.Instance}}"
            Icon="menu_status.png">
    <ShellContent x:Name="MainShell"
                  Title="{Binding [MainPage], Source={x:Static util:Translator.Instance}}"
                  Icon="menu_status.png"
                  ContentTemplate="{DataTemplate views:PlatformPage}"
                  Route="MainPageRoute">
        <ShellContent.SearchHandler>
            <handlers:CustomSearchHandler x:Name="CustomSearchHandler" BindingContext="{Binding Source={x:Reference Name=MainPageViewModel}}"
                Placeholder="{Binding [SearchCustomCode], Source={x:Static util:Translator.Instance}}">
                <handlers:CustomSearchHandler.ItemTemplate>
                    <DataTemplate x:DataType="models:CustomModel">
                        <Label Margin="2,4" Text="{Binding Name}"></Label>
                    </DataTemplate>
                </handlers:CustomSearchHandler.ItemTemplate>
            </handlers:CustomSearchHandler>
        </ShellContent.SearchHandler>
    </ShellContent>
</FlyoutItem>

方案2:监听Shell导航事件,手动恢复SearchHandler

在Shell的代码后台添加导航事件监听,当导航回主FlyoutItem的路由时,重新设置SearchHandler的可见性或重新绑定:

public partial class AppShell : Shell
{
    public AppShell()
    {
        InitializeComponent();
        Navigated += AppShell_Navigated;
    }

    private void AppShell_Navigated(object sender, ShellNavigatedEventArgs e)
    {
        // 判断是否回到主页面路由
        if (e.Current.Location.OriginalString.Contains("MainPageRoute"))
        {
            // 确保SearchHandler实例存在并设置ShowsResults为true
            if (CustomSearchHandler != null)
            {
                CustomSearchHandler.ShowsResults = true;
                // 若绑定丢失可重新设置BindingContext
                CustomSearchHandler.BindingContext = MainPageViewModel;
            }
        }
    }
}

方案3:禁用ShellContent的缓存(不推荐,影响性能)

如果是因为ShellContent的缓存机制导致页面实例被复用但SearchHandler未正确初始化,可以禁用缓存:

<ShellContent x:Name="MainShell"
              Title="{Binding [MainPage], Source={x:Static util:Translator.Instance}}"
              Icon="menu_status.png"
              ContentTemplate="{DataTemplate views:PlatformPage}"
              Route="MainPageRoute"
              CacheMode="Disabled" />

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 23:32:28