C# 父级上的事件处理程序从子级捕获事件

C# 父级上的事件处理程序从子级捕获事件,c#,wpf,events,C#,Wpf,Events,可能我还没有真正理解WPF中的事件系统 我有一个TabItem,它的标题由一个文本框和一个按钮组成。文本框是只读的。(在实际应用程序中,它允许双击进行编辑,但这与此处无关。) 很难选择选项卡,因为文本框捕获MouseLeftButtonDown事件。因此,我在TabItem中添加了一个事件处理程序,将其带到前台。但是,对于该事件处理程序,按钮不再接收事件。为什么按钮在TabItem获取事件之前不获取事件?我以为它是从叶子到逻辑树的根冒出来的 以下是XAML: <Window x:Class

可能我还没有真正理解WPF中的事件系统

我有一个TabItem,它的标题由一个文本框和一个按钮组成。文本框是只读的。(在实际应用程序中,它允许双击进行编辑,但这与此处无关。)

很难选择选项卡,因为文本框捕获MouseLeftButtonDown事件。因此,我在TabItem中添加了一个事件处理程序,将其带到前台。但是,对于该事件处理程序,按钮不再接收事件。为什么按钮在TabItem获取事件之前不获取事件?我以为它是从叶子到逻辑树的根冒出来的

以下是XAML:

<Window x:Class="tt_WPF.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:tt_WPF"
    Title="MainWindow" SizeToContent="WidthAndHeight">
<TabControl x:Name="TC"></TabControl> 
</Window>  

你所面对的事情叫做。要防止事件被路由到下一级,必须设置
Handled=true
。您还可以检查引发此事件的发件人类型,以过滤掉不必要的呼叫

private void TabItem_MouseLeftButtonDownEvent(object sender, RoutedEventArgs e)
{
    this.IsSelected = true;
    e.Handled = true;
}
当涉及到用户输入()时,有一个非常好的图表显示事件路由:


因此,要获得所需的自底向上路由路径,您需要通过使用
PreviewLeftMouseButtonDown
将行为更改为
Bubble
,而不是
Tunnel
,当我将
e.Handled=true
放入
选项卡项_MouseLeftButtonDownEvent()
时,这并没有什么区别;我希望事件首先出现在按钮上,然后出现在包含的选项卡项上。感谢Anatolii,将事件更改为预览类型成功了。(我有一本教科书说MouseLeftButtonDown是Bubble类型的,这似乎是错误的;它还提到MSDN显示了直接的策略)。不过我还是很困惑。假设MouseLeftButtonDown是隧道:当我将AddHandler(HandledEventsToo)的第三个参数设置为false时,事件处理程序不再被调用,但按钮接收事件。只有当这是一个冒泡事件时,这对我来说才有意义。另外:如果它是隧道设置,e.Handled设置为false应该指示事件在树上进一步移动。但这也没有发生。我有一种强烈的感觉,您所面临的问题与您在代码隐藏(将检查并确认)上创建CONRTOL的事实有关。试试xaml吧。我真正的程序是用xaml编写的。我把它放在代码中,以便在发布时更加连贯。错误完全相同。你有没有检查过VS中的代码?
private void TabItem_MouseLeftButtonDownEvent(object sender, RoutedEventArgs e)
{
    this.IsSelected = true;
    e.Handled = true;
}