RoutedEventArgs.OriginalSource 是如何计算出来的?
How is RoutedEventArgs.OriginalSource computed?
我看过 and in the MS docs是命中测试决定的,但是这个问题最后的例子是反对这个的,目前我是这么理解的。
Here 我读到它是引发事件的第一个对象,但我不知道这是什么意思,即在下面的示例中。
我目前的理解
鉴于此代码:
private void Handler(object sender, RoutedEventArgs e)
{
// what does it mean here: sender, e.Source and e.OriginalSource ?
}
- sender - 处理事件的元素(处理程序附加到该元素)
- e.Source - 事件开始在可视化树中进行的元素(从上到下,或从下到上)
- e.OriginalSource - 通过命中测试确定的最深元素,它位于事件开始通过可视化树进行的元素内部
例子
给定以下来源的可视化树XAML:
<StackPanel x:Name="sp" Button.Click="Handler">
<Button x:Name="btn1">button 1</Button>
<Button x:Name="btn2">button 2</Button>
<Button x:Name="btn3" Padding="5">
<Rectangle Width="100" Height="100" Fill="Blue" x:Name="r"/>
</Button>
</StackPanel>
和上面相同的处理程序:
private void Handler(object sender, RoutedEventArgs e)
{
// what does it mean here: sender, e.Source and e.OriginalSource ?
}
点击时:
btn1
:sender
将是 sp
,e.Source
将是 btn1
,e.OriginalSource
将是 btn1
btn2
:sender
将是 sp
,e.Source
将是 btn2
,e.OriginalSource
将是 btn2
btn3
:sender
将是 sp
,e.Source
将是 btn3
,e.OriginalSource
将是:
r
如果点击蓝色Rectangle
(这里我错了,不知道为什么)
btn3
如果点击是在 btn3
中的 space 周围 r
而不是上面列表中最新元素中的 r
,我得到 e.OriginalSource == btn3
。
官方文档是here。
谢谢。
Rectangle
不会引发您处理的任何 Button.Click
事件。但是,它确实会引发 MouseLeftButtonDown
(Button
在内部处理),您可以确认是否处理 StackPanel
的 PreviewMouseLeftButtonDown
并检查 OriginalSource
属性 在事件处理程序中。
你击中的东西开始滚动。
或者更准确地说。
事件冒泡。
路由事件可以在可视化树中向上冒泡或向下隧道化。
文档试图对此进行解释:
https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/routed-events-overview
这意味着你点击了某个东西,然后它变成了事件的原始来源。首先解决这个问题,因为它将驱动一切。后面不计算了。
它在可视化树中上下移动,设置的源将取决于您处理事件的位置。
我看过
Here 我读到它是引发事件的第一个对象,但我不知道这是什么意思,即在下面的示例中。
我目前的理解
鉴于此代码:
private void Handler(object sender, RoutedEventArgs e)
{
// what does it mean here: sender, e.Source and e.OriginalSource ?
}
- sender - 处理事件的元素(处理程序附加到该元素)
- e.Source - 事件开始在可视化树中进行的元素(从上到下,或从下到上)
- e.OriginalSource - 通过命中测试确定的最深元素,它位于事件开始通过可视化树进行的元素内部
例子
给定以下来源的可视化树XAML:
<StackPanel x:Name="sp" Button.Click="Handler">
<Button x:Name="btn1">button 1</Button>
<Button x:Name="btn2">button 2</Button>
<Button x:Name="btn3" Padding="5">
<Rectangle Width="100" Height="100" Fill="Blue" x:Name="r"/>
</Button>
</StackPanel>
和上面相同的处理程序:
private void Handler(object sender, RoutedEventArgs e)
{
// what does it mean here: sender, e.Source and e.OriginalSource ?
}
点击时:
btn1
:sender
将是sp
,e.Source
将是btn1
,e.OriginalSource
将是btn1
btn2
:sender
将是sp
,e.Source
将是btn2
,e.OriginalSource
将是btn2
btn3
:sender
将是sp
,e.Source
将是btn3
,e.OriginalSource
将是:r
如果点击蓝色Rectangle
(这里我错了,不知道为什么)btn3
如果点击是在btn3
中的 space 周围r
而不是上面列表中最新元素中的 r
,我得到 e.OriginalSource == btn3
。
官方文档是here。
谢谢。
Rectangle
不会引发您处理的任何 Button.Click
事件。但是,它确实会引发 MouseLeftButtonDown
(Button
在内部处理),您可以确认是否处理 StackPanel
的 PreviewMouseLeftButtonDown
并检查 OriginalSource
属性 在事件处理程序中。
你击中的东西开始滚动。
或者更准确地说。
事件冒泡。
路由事件可以在可视化树中向上冒泡或向下隧道化。
文档试图对此进行解释:
https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/routed-events-overview
这意味着你点击了某个东西,然后它变成了事件的原始来源。首先解决这个问题,因为它将驱动一切。后面不计算了。
它在可视化树中上下移动,设置的源将取决于您处理事件的位置。