none
WPF 隧道事件 与 冒泡事件 的研究 RRS feed

  • 问题

  • <Window x:Class="构建并部署应用程序.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525"
            Activated="Window_Activated"
            Deactivated="Window_Deactivated" 
            
            PreviewMouseDown="Window_PreviewMouseDown"
            PreviewMouseUp="Window_PreviewMouseUp"
            
            MouseDown="Window_MouseDown"
            MouseUp="Window_MouseUp"
            >
        <Grid>
            <Button x:Name="btnTest" Width="100" Height="50"
                    PreviewMouseDown="btnTest_PreviewMouseDown"
                    PreviewMouseUp="btnTest_PreviewMouseUp"
                    
                    MouseDown="btnTest_MouseDown"
                    MouseUp="btnTest_MouseUp"
                    >路由事件</Button>
        </Grid>
    </Window>
            private void Window_PreviewMouseDown(object sender, MouseButtonEventArgs e)
            {
                Console.WriteLine("隧道事件 - " + "Window_PreviewMouseDown " 
                    + " - Source: " + e.Source 
                    + " - OriginalSource: " + e.OriginalSource
                    + " - Timestamp: " +e.Timestamp);
            }
    
            private void Window_PreviewMouseUp(object sender, MouseButtonEventArgs e)
            {
                Console.WriteLine("隧道事件 - " + "Window_PreviewMouseUp "
                                    + " - Source: " + e.Source
                                    + " - OriginalSource: " + e.OriginalSource
                                    + " - Timestamp: " + e.Timestamp);
            }
    
            private void btnTest_PreviewMouseDown(object sender, MouseButtonEventArgs e)
            {
                Console.WriteLine("隧道事件 - " + "btnTest_PreviewMouseDown "
                                    + " - Source: " + e.Source
                                    + " - OriginalSource: " + e.OriginalSource
                                    + " - Timestamp: " + e.Timestamp);
            }
    
            private void btnTest_PreviewMouseUp(object sender, MouseButtonEventArgs e)
            {
                Console.WriteLine("隧道事件 - " + "btnTest_PreviewMouseUp "
                                    + " - Source: " + e.Source
                                    + " - OriginalSource: " + e.OriginalSource
                                    + " - Timestamp: " + e.Timestamp);
            }
    
            private void Window_MouseDown(object sender, MouseButtonEventArgs e)
            {
                Console.WriteLine("冒泡事件 - " + "Window_MouseDown "
                                    + " - Source: " + e.Source
                                    + " - OriginalSource: " + e.OriginalSource
                                    + " - Timestamp: " + e.Timestamp);
            }
    
            private void Window_MouseUp(object sender, MouseButtonEventArgs e)
            {
                Console.WriteLine("冒泡事件 - " + "Window_MouseUp "
                                    + " - Source: " + e.Source
                                    + " - OriginalSource: " + e.OriginalSource
                                    + " - Timestamp: " + e.Timestamp);
            }
    
            private void btnTest_MouseDown(object sender, MouseButtonEventArgs e)
            {
                Console.WriteLine("冒泡事件 - " + "btnTest_MouseDown "
                                    + " - Source: " + e.Source
                                    + " - OriginalSource: " + e.OriginalSource
                                    + " - Timestamp: " + e.Timestamp);
            }
    
            private void btnTest_MouseUp(object sender, MouseButtonEventArgs e)
            {
                Console.WriteLine("冒泡事件 - " + "btnTest_MouseUp "
                                    + " - Source: " + e.Source
                                    + " - OriginalSource: " + e.OriginalSource
                                    + " - Timestamp: " + e.Timestamp);
            }

    运行过程:

    1.在窗口内(非Button区域)点击

    产生如下结果:

    隧道事件 - Window_PreviewMouseDown  - Source: 构建并部署应用程序.MainWindow - OriginalSource: System.Windows.Controls.Border - Timestamp: 80518937
    冒泡事件 - Window_MouseDown  - Source: 构建并部署应用程序.MainWindow - OriginalSource: System.Windows.Controls.Border - Timestamp: 80518937
    隧道事件 - Window_PreviewMouseUp  - Source: 构建并部署应用程序.MainWindow - OriginalSource: System.Windows.Controls.Border - Timestamp: 80519031
    冒泡事件 - Window_MouseUp  - Source: 构建并部署应用程序.MainWindow - OriginalSource: System.Windows.Controls.Border - Timestamp: 80519031

    2.在Button区域内点击

    产生如下结果:

    隧道事件 - Window_PreviewMouseDown  - Source: System.Windows.Controls.Button: 路由事件 - OriginalSource: System.Windows.Controls.TextBlock - Timestamp: 80569234
    隧道事件 - btnTest_PreviewMouseDown  - Source: System.Windows.Controls.Button: 路由事件 - OriginalSource: System.Windows.Controls.TextBlock - Timestamp: 80569234
    隧道事件 - Window_PreviewMouseUp  - Source: System.Windows.Controls.Button: 路由事件 - OriginalSource: System.Windows.Controls.Button: 路由事件 - Timestamp: 80569312
    隧道事件 - btnTest_PreviewMouseUp  - Source: System.Windows.Controls.Button: 路由事件 - OriginalSource: System.Windows.Controls.Button: 路由事件 - Timestamp: 80569312

    我的疑问是:

    1.在Button区域内点击时,为何没有冒泡事件?只有隧道事件

    2.观察

    隧道事件 - Window_PreviewMouseUp  - Source: System.Windows.Controls.Button: 路由事件 - OriginalSource: System.Windows.Controls.Button: 路由事件 - Timestamp: 80569312
    隧道事件 - btnTest_PreviewMouseUp  - Source: System.Windows.Controls.Button: 路由事件 - OriginalSource: System.Windows.Controls.Button: 路由事件 - Timestamp: 80569312

    请问此处的OriginalSource为何是System.Windows.Controls.Button 而不是System.Windows.Controls.Border或者

    System.Windows.Controls.TextBlock

    我想我对于OriginalSource的理解还是有些问题,想请教触发事件中为什么有时候是

    System.Windows.Controls.Border/System.Windows.Controls.TextBlock/System.Windows.Controls.Button


    感激不尽,这个对于我理解路由事件中的隧道事件和冒泡事件有着重要的作用

    2014年4月25日 1:37

答案

  • 1,button是没有左键点击的MouseDown和MouseUp事件的,换一个控件测试比较合适,比如你可以直接把Button换成Label就能正确看到冒泡事件了。

    2,button在过滤左键点击的MouseDown和MouseUp事件时,内部调用了Mouse.Capture(button),这样就改变了OriginalSource,所以你看到的OriginalSource就是Button而不是其他的UIElement。

    鼠标事件的OriginalSource可以看成是当前捕获鼠标的UIElement。你可以试一下在窗体里面添加另一个控件,比如Label,然后在button的PreviewMouseDown事件里面调用Mouse.Capture(label),你会发现在紧接着的PreviewMouseUp事件里面,OriginalSource就是label了。

    • 已标记为答案 Wayne1900 2014年4月25日 5:18
    2014年4月25日 3:48