如何从子控件使用 Command.CanExecute
本文关键字:Command CanExecute 控件 | 更新日期: 2023-09-27 18:30:49
这是设置(删除了无关的布局代码):
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
检查当前页面是否是最后一页。但是,该逻辑目前仅检查数组,仅适用于线性导航。但是,导航将是树状的,这将不起作用,其中contentControl1
中的项目有时会向不同的方向分支。因此,我希望CurrentPage
的用户控件有机会覆盖CanExecute
。我的问题是我无法弄清楚如何让UserControl
开始CanExecute
。我尝试使用许多CommandTarget
设置无济于事......我的子控件从未触发过CanExecute
方法。我什至尝试在父窗口的 CanExecute 中使用e.ContinueRouting = true
。这是用户控制代码,以防万一。
用户控制控制器:
var nextCommand = new CommandBinding(NavigationCommands.NextPage);
nextCommand.CanExecute += nextCommand_CanExecute;
CommandBindings.Add(nextCommand);
用户控件可以执行方法:
private void nextCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = false;
e.Handled = true;
}
路由命令事件从可视化树的根向下隧道到启动它们的控件,然后冒泡回来。Josh Smith 关于路由命令的文章很好地描述了它的工作原理(特别是"路由"部分)http://joshsmithonwpf.wordpress.com/2008/03/18/understanding-routed-commands/。
这里的问题是,您的用户控件(在内容控件内部)不是发出命令的按钮的"祖先",因此路由事件永远不会到达它(即使是传递)。鉴于可视化树的结构方式,我认为路由命令对您来说是不够的。
我想到的第一个解决方案是装配您自己的机制,用于将 CanExecute/Execute 逻辑委派给用户控件。也许您可以定义一个由所有此类控件实现的基类或接口,该基类或接口定义了所需的各种命令CanExecute/Execute方法。然后,您可以只使用一个顶级实现,它将当前加载的控件强制转换为接口/基类类型并调用适当的方法。