0

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

窗口.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触发过它的方法。我什至尝试e.ContinueRouting = true在父窗口的 CanExecute 中使用。这是用户控制代码,以防万一。

用户控制构造器:

  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;
}
4

1 回答 1

2

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

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

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

于 2012-04-10T17:06:31.510 回答