在WPF中如何将命令转发到子控件?

时间:2011-12-01 19:40:24

标签: wpf mvvm

我有类似MVVM的情况(不使用任何框架),我有一个带有工具栏和文档区域的主窗口。这些文档具有命令绑定(例如Undo和Redo)。当键盘焦点位于文档之外时,它不知道如何执行任何命令,因此按钮将被禁用。

我想要做的是添加一种机制,主窗口将命令转发到活动文档(如果有的话)。使用CommandManager.AddPreviewCanExecuteHandler我可以在主窗口中获取事件,但我无法弄清楚如何将它们发送到子文档 - 我尝试e.CanExecute = e.Command.CanExecute(CurrentDocument),但这最终会重新调用再次PreviewCanExecuteHandler,并且不调用子项的CanExecute处理程序。

如何将任意ICommand发送到子控件?

2 个答案:

答案 0 :(得分:1)

答案是here - 致电CurrentDocument.RaiseEvent(e),确保通过注册了CommandManager.AddCanExecuteHandler(不是AddPreviewCanExecuteHandler)的处理程序来完成。并确保检查无限递归。

答案 1 :(得分:0)

据推测,您有一些管理活动文档的机制 - 枚举它们,识别活动文档等。

我建议不要考虑从主窗口获取命令并将它们转发到文档,而是将其视为采用活动文档中可用的命令并将它们附加到主窗口。

无论您在文档中使用哪种通用接口,都要添加一些属性:

ICommand Undo { get; }
ICommand Redo { get; }

现在,您将主窗口的控件绑定到ActiveDocument.UndoActiveDocument.Redo,其中ActiveDocument是主窗口视图模型中的属性。 ActiveDocument更改后,您将收到属性更改通知,以便相应地启用/禁用按钮。

顺便说一句,当我完成相似的操作时,我会暴露一些复合对象,其中ICommands是属性,但具有单独的CanUndo / CanRedo布尔属性和其他元数据 - 给我一个更好的抽象,通过它来控制基于命令堆栈状态的启用和禁用。

相关问题