天天看點

【WPF】ListBox嵌套與事件冒泡

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

參考: