如何从子控件使用Command.CanExecute

时间:2012-04-10 15:59:57

标签: c# .net wpf command

以下是设置(删除了无关的布局代码):

Window.xaml

<Button Name="btn_Next" Command="NextPage">Next</Button>
<ContentControl Name="contentControl1" >
        <Binding ElementName="MainWindow" Path="CurrentPage"/>
</ContentControl>

Window.xaml.cs构造函数

  var nextCommand = new CommandBinding(NavigationCommands.NextPage);
  nextCommand.CanExecute += nextCommand_CanExecute;
  nextCommand.Executed += nextCommand_Executed;
  CommandBindings.Add(nextCommand);

这在基本示例中很有用,其中nextCommand_CanExecute检查CurrentPage是否是最后一页。但是,该逻辑目前只是检查数组,仅适用于线性导航。但是,导航将是树状的,这将不起作用,contentControl1中的项目有时会分支到不同的方向。所以,我希望CurrentPage的用户控件有机会覆盖CanExecute。我的问题是我无法弄清楚如何让UserControl启动CanExecute。我试图使用一些CommandTarget设置无济于事...我的孩子控制从未触发过CanExecute方法。我甚至试图在父窗口的CanExecute中使用e.ContinueRouting = true。如果有帮助,这是用户控制代码。

用户控制Constrtuctor:

  var nextCommand = new CommandBinding(NavigationCommands.NextPage);
  nextCommand.CanExecute += nextCommand_CanExecute;
  CommandBindings.Add(nextCommand);

用户控制CanExecute方法:

private void nextCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
  e.CanExecute = false;
  e.Handled = true;
}

1 个答案:

答案 0 :(得分:2)

路由命令事件从可视树的根向下隧道传输到启动它们的控件,然后向后冒泡。 Josh Smith关于路由命令的文章很好地描述了它的工作原理(特别参见“路由”部分)http://joshsmithonwpf.wordpress.com/2008/03/18/understanding-routed-commands/

这里的问题是你的用户控件(在内容控件内部)不是发出命令的按钮的“祖先”,因此路由事件永远不会到达它(即使在传递中)。鉴于您的可视树的结构方式,我不认为路由命令对您来说足够了。

首先想到的解决方案是绑定您自己的机制,将CanExecute / Executed逻辑委派给您的用户控件。也许您可以定义由所有此类控件实现的基类或接口,这些控件定义了所需的各种命令CanExecute / Executed方法。然后你可以只有一个顶级实现,它将当前加载的控件作为你的接口/基类类型抛出并调用适当的方法。