原文:
【WPF】ListBox嵌套与事件冒泡
问题:两个ListBox嵌套后,当鼠标位于内部ListBox上,鼠标滚轮事件会被内部ListBox接收,导致外层ListBox不能用鼠标滚轮滑动!现在的需求是该事件要能给外部ListBox处理,即嵌套的ListBox应该由外层ListBox来接收鼠标滚轮事件。
<ListBox> <ListBox> <ListBox.ItemTemplate> <DataTemplate> <!-- 省略 --> </DataTemplate> <ListBox.ItemTemplate> </ListBox> </ListBox>
思路:根据WPF的冒泡路由事件,鼠标滚轮事件首先会被内层的ListBox接收。此时该事件被拦截后直接将它标记为已处理(不让内部ListBox的滚轮滑动),然后再手动激发一个鼠标滚轮事件,该事件自动向上冒泡就能被外层ListBox接收到。
给内层ListBox注册一个鼠标滚轮事件。
<ListBox x:Name="innerLB" PreviewMouseWheel="innerLB_PreviewMouseWheel">
后台代码处理该事件。
/// <summary> /// 问题:内层的ListBox拦截了鼠标滚轮事件,导致外层ListBox不能用鼠标滚轮滑动。 /// 办法:内层ListBox拦截鼠标滚轮事件后,再手动激发一个鼠标滚轮事件,让事件冒泡给外层ListBox接收到。 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void innerLB_PreviewMouseWheel(object sender, MouseWheelEventArgs e) { if (!e.Handled) { // 内层ListBox拦截鼠标滚轮事件 e.Handled = true; // 激发一个鼠标滚轮事件,冒泡给外层ListBox接收到 var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta); eventArg.RoutedEvent = UIElement.MouseWheelEvent; eventArg.Source = sender; var parent = ((Control)sender).Parent as UIElement; parent.RaiseEvent(eventArg); } }
参考: