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

WinUI 3:切换选中项时如何折叠导航菜单项

WinUI 3 导航菜单切换时折叠未选中项且保留选中动画的解决方法

你遇到的问题是因为在SelectionChanged事件里同步修改非选中项的IsExpanded属性,打断了导航菜单控件内部的选中指示器动画流程——控件还在处理选中状态的过渡动画,就被强制修改了展开状态,导致动画异常。

下面是两种可行的解决思路:

方法一:延迟执行折叠操作

通过延迟修改IsExpanded,让控件先完成选中动画,再处理折叠逻辑:

步骤1:提前收集所有导航菜单项

先在导航菜单加载时,递归收集所有层级的菜单项,避免每次切换都重新遍历:

private List<NavigationViewItemBase> _allNavItems = new();

private void NavView_Loaded(object sender, RoutedEventArgs e)
{
    var navView = sender as NavigationView;
    CollectAllItems(navView.MenuItems, _allNavItems);
}

private void CollectAllItems(IEnumerable menuItems, List<NavigationViewItemBase> itemsList)
{
    foreach (var item in menuItems)
    {
        if (item is NavigationViewItemBase navItem)
        {
            itemsList.Add(navItem);
            if (navItem is NavigationViewItem parentItem)
            {
                CollectAllItems(parentItem.MenuItems, itemsList);
            }
        }
    }
}

步骤2:在SelectionChanged中延迟折叠

用Task.Delay让折叠操作等动画完成后再执行:

private async void NavView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
    // 等待100ms让选中动画完成,可根据实际效果微调时长
    await Task.Delay(100);

    foreach (var item in _allNavItems)
    {
        if (item is NavigationViewItem navItem && navItem != args.SelectedItem)
        {
            navItem.IsExpanded = false;
        }
    }
}

方法二:MVVM模式下的绑定控制

如果用MVVM开发,可以给每个菜单项的ViewModel添加IsSelected和IsExpanded属性,通过绑定实现联动:

  1. ViewModel中,当某个项的IsSelected设为true时,遍历其他项并延迟设置IsExpanded = false
  2. XAML中绑定NavigationViewItem的IsSelected和IsExpanded到ViewModel对应属性:
<NavigationViewItem IsSelected="{Binding IsSelected}" IsExpanded="{Binding IsExpanded}" />

这种方式更贴合MVVM架构,也能避免直接操作控件带来的状态冲突。

注意点

  • 延迟时间不用太长,100ms基本能覆盖WinUI 3的选中动画时长,可根据实际显示效果调整
  • 如果菜单有动态加载的项,要在项更新后重新调用收集方法,确保所有项都被纳入处理

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

相关产品推荐
方舟 Agent Plan

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

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