WPF左侧垂直带Expander的用户控件菜单单选折叠功能问题咨询
问题根源
该问题由事件重复处理和逻辑缺陷共同导致:
- 事件触发顺序冲突:
PreviewMouseDown是隧道事件,会优先执行你自定义的处理逻辑,将当前点击的菜单设为打开状态;随后事件冒泡到Expander控件的内置点击处理逻辑,Expander会自动切换IsExpanded属性,又将刚打开的菜单切回关闭状态,就出现了刚打开就关闭的闪烁现象。 - 原有逻辑不合理:无论当前点击的菜单处于什么状态,都强制设置为打开,用户无法主动关闭已打开的菜单。
修复步骤
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
相关产品推荐
相关产品推荐

