【问题标题】:Prevent child controls from receiving routed events阻止子控件接收路由事件
【发布时间】:2015-12-22 06:11:19
【问题描述】:

假设我在可视化树的某处有我的用户控件。父母和孩子是我无法修改的第 3 方控件。我想过滤我的控件中的键盘事件,以便 children 控件不会接收到某些键盘事件,但父控件会接收。

我将尝试用一些图表来解释我想要实现的目标。如果控件不处理键盘事件,则所有事件都会通过可视化树反弹:

但是,f.e.当用户按下 A,

  1. Child2.OnPreviewKeyDown() 不应该被调用
  2. Parent2.OnTextInput 仍应收到一个事件

我可以通过在MyControl.PreviewKeyDown 中设置e.Handled = true 来实现(1)。问题是在这种情况下TextInput 事件不会生成:

有没有办法实现第二张图片中的行为?

添加: 我要解决的问题是第 3 方控件(子 2)窃取了 OnPreviewKeyDown 中的一些输入(并将事件标记为已处理),我正在努力避免这种情况。

【问题讨论】:

  • Parent2 无法处理 PreviewKeyDown 而不是 Keydown?
  • 我认为如果没有一些重大的黑客攻击,您的要求是不可能的(阅读:易碎且不可取)。想到的事情是处理预览事件并重新引发父事件。或者也许有一种方法可以通过反射断开 Child2 中的处理程序。不过,这些东西都不是很可口。
  • 没有办法阻止事件发生,但是您可以使用if (myhandler) return 提前退出,其中my handler 应该是您自定义的布尔值以使其成为true/false根据您的需要
  • @PScr 不幸的是没有。只有当输入未被任何其他控件处理时,父 2 才应处理输入。而且我的图像中有一个错误:Parent 使用 TextInput 事件,而不是 KeyDown 事件。

标签: c# .net wpf routed-events


【解决方案1】:

您通常可以在 WPF 中处理抑制事件的方法是在代码中添加处理程序并重新引发事件。为此,您可以使用UIElement.AddHandler() 方法,例如:

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

即使设置了 Handled 标志,'true' 布尔值也会使 nameOfYourHandlerFunction 触发。该事件不会自动重新冒泡,因此您需要再次引发该事件。

base.RaiseEvent(e);

这适用于具有 Bubble 路由策略的事件。

【讨论】:

  • 根据他写的:他不能在 Parent2 中附加一个处理程序,因为它是一个内部的 3rd 方控件,因此他不能像你描述的那样添加这个处理程序。此外,我相信处理预览键按下事件会阻止 TextInput 事件被触发,因此这也不起作用。
  • 带家长控制的情况比带孩子好。我可以参考它。但无论如何,如果处理了 KeyDown 或 KeyUp,则根本不会触发 TextInput 事件。
  • 好吧,或者,您可以手动处理和重新引发 child2 上的 KeyDown 或 KeyUp 事件(以消耗的为准),其方式与让路由事件继续冒泡通过 child2 的方式大致相同.如果 AddHandler 函数真的不能在 child2 上工作,我真的会感到惊讶,除非它不是 WPF 控件(例如,如果您托管的是 Windows 窗体控件)。即使设置了 Handled 标志,WPF 中的路由事件仍会转发到下一个侦听器。在 AddHandler 中设置 'true' 标志是提供处理此类事件的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多