使用隧道而不是冒泡的RoutedCommands

时间:2012-10-04 11:28:35

标签: c# wpf command routed-commands tunneling

我有一个自定义控件(MyControl),它公开了一个自定义命令。我希望父Window能够调用此命令,并且所有MyControls都应该对它做出反应。

我已将命令添加到MyControl的{​​{1}}集合中,该集合还提供始终返回true的CommandBindings回调。

我的问题是调用此命令的菜单项永远不会启用。我认为这是因为菜单位于可视化树中的CanExecute之上,但说实话,我对MyControls范围内的工作原理一无所知

有人可以澄清我做错了什么,或者这是否可能?

2 个答案:

答案 0 :(得分:1)

我猜这里的命令是错误的。

命令用于将不同的命令触发源捆绑到一个命令处理程序。 因此命令是从不同的控件,菜单触发的......但是调用相同的命令处理程序。

事件是一种对立面。 一个源可以触发多个事件处理程序。

在您的特殊情况下,我更喜欢一个事件,而您的UI树下面的控件比听取隧道事件或冒泡事件要好。

答案 1 :(得分:0)

是的,重点是您的自定义命令的CommandBinding低于可视树中的菜单项。来自msdn

  

调用RoutedCommand上的CanExecute方法时,会在命令目标上引发PreviewCanExecute事件。如果未处理该事件,则引发CanExecute事件。如果命令目标具有该命令的CommandBinding,则调用该CommandBinding的CanExecute处理程序。 如果命令目标没有命令的CommandBinding,则CanExecute事件会冒泡元素树,搜索具有与命令关联的CommandBinding的元素。

关于at this link中命令的非常好的文章。

无论如何,您可以使用CommandTarget菜单项中的命令,例如

<MenuItem Header="Click me"  Command="local:CommandClass.MyCustomCommand" CommandTarget="{Binding ElementName=myCustomCtrl}" />

通过这种方式,特定的命令源(菜单项)将命令定向到特定目标(自定义控件的实例)。