原文: 【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);
}
}
參考: