简体   繁体   English

防止子控件接收路由事件

[英]Prevent child controls from receiving routed events

Lets say I have my user-control somewhere in the visual tree. 可以说,我的用户控件位于可视化树的某个位置。 Parent and children are 3rd-party controls that I cannot modify. 父母和孩子是我无法修改的第三方控件。 I want to filter keyboard events in my control so that children controls do not receive some keyboard events, but the parent controls do. 我想过滤控件中的键盘事件,以便控件不接收某些键盘事件,而父控件接收。

I'll try to explain what I want to achieve with some diagrams. 我将尝试通过一些图表来说明我想要实现的目标。 If controls do not handle keyboard events, all events bounce through the visual tree: 如果控件不处理键盘事件,则所有事件都会通过可视树反弹:

在此处输入图片说明

But, fe when user presses A , 但是,当用户按下A时

  1. Child2.OnPreviewKeyDown() should NOT be called 不应该调用Child2.OnPreviewKeyDown()
  2. but Parent2.OnTextInput should still receive an event Parent2.OnTextInput仍应收到一个事件 在此处输入图片说明

I can achive (1) by setting e.Handled = true in MyControl.PreviewKeyDown . 我可以通过在MyControl.PreviewKeyDown e.Handled = true设置为(1)。 The problem is that in this case TextInput event is not generated: 问题在于在这种情况下不会生成TextInput事件: 在此处输入图片说明

Is there a way to achieve behavior like on the 2nd picture? 有没有办法实现第二张图片上的行为?

Added: The problem I'm trying to solve is that a 3rd-party control (Child 2) steals some input in OnPreviewKeyDown (and marks event as handled), and I'm trying to avoid that. 补充:我要解决的问题是第3方控件(子级2)在OnPreviewKeyDown中窃取了一些输入(并将事件标记为已处理),而我试图避免这种情况。

What you can generally do in WPF to handle a suppressed event is add a handler in code and re-raise the event. 通常,在WPF中可以处理被抑制的事件的方法是在代码中添加一个处理程序,然后重新引发该事件。 To do this, you use the UIElement.AddHandler() method, for example: 为此,请使用UIElement.AddHandler()方法,例如:

child2.AddHandler(UIElement.TextInput, new TextCompositionEventHandler(nameOfYourHandlerFunction), true);

The 'true' boolean value is what makes nameOfYourHandlerFunction fire even if the Handled flag is set. 即使设置了Handled标志,布尔值'true'也会使nameOfYourHandlerFunction触发。 The event won't automatically re-bubble by doing that, so you need to raise the event again. 这样做不会自动重新引发事件,因此您需要再次引发事件。

base.RaiseEvent(e);

This works for events that have a routing strategy of Bubble. 这适用于具有气泡路由策略的事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM