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

WPF左侧垂直带Expander的用户控件菜单单选折叠功能问题咨询

问题根源

该问题由事件重复处理和逻辑缺陷共同导致:

  1. 事件触发顺序冲突:PreviewMouseDown是隧道事件,会优先执行你自定义的处理逻辑,将当前点击的菜单设为打开状态;随后事件冒泡到Expander控件的内置点击处理逻辑,Expander会自动切换IsExpanded属性,又将刚打开的菜单切回关闭状态,就出现了刚打开就关闭的闪烁现象。
  2. 原有逻辑不合理:无论当前点击的菜单处于什么状态,都强制设置为打开,用户无法主动关闭已打开的菜单。

修复步骤

1. 调整用户控件XAML的绑定配置

给Expander的IsExpanded绑定添加双向模式,保证依赖属性和控件状态双向同步:

<Expander x:Name="ExpanderMenu" 
          Header="{Binding Path=Header}" 
          IsExpanded="{Binding Path=IsSelected, Mode=TwoWay}" 
          Width="210" 
          HorizontalAlignment="Right" 
          Background="{x:Null}">
    <ContentControl Content="{Binding ListView}"/>
</Expander>

2. 优化主窗口的点击事件逻辑

修改PreviewMouseDown事件处理代码,新增状态切换逻辑,同时阻止事件继续传播避免重复处理:

private void MenuItemHome_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    var currentMenu = sender as UserControlMenuItem;
    if (currentMenu == null) return;

    // 记录当前菜单点击前的状态
    bool originSelectedState = currentMenu.IsSelected;

    // 关闭所有菜单
    foreach (var item in st_menu.Children)
    {
        if (item is UserControlMenuItem menuItem)
        {
            menuItem.IsSelected = false;
        }
    }

    // 切换当前菜单状态:原状态为关闭则打开,原状态为打开则保持关闭
    currentMenu.IsSelected = !originSelectedState;

    // 标记事件已处理,阻止冒泡到Expander的内置点击逻辑
    e.Handled = true;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 15:27:04