我继承了针对旧版本 Prism(复合应用程序指南 1.0)开发的 WPF 应用程序。此应用程序中的一般模式是在 ViewModel 中使用 Microsoft.Practices.Composite.Wpf.DelegateCommand 并避免代码隐藏事件处理程序。它使用 MVP 模式,其中 Presenter 表示 XAML 绑定到的 ViewModel。
我有一个带有 ContextMenu 的 DataGrid,XAML 绑定如下所示:
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Do Stuff" Command="{Binding DoStuffCommand.Command}" />
</ContextMenu>
</DataGrid.ContextMenu>
DoStuffCommand 实际上是一个自定义的 CommandBase 对象,它作为一个属性暴露在 Presenter 上。DoStuffCommand.Command 是实际的 DelegateCommand 对象。DelagateCommand 是使用 Presenter 中定义的 Execute 和 CanExecute 方法构造的(this.DoStuff、this.DoStuffCanExecute)。
在第一次右键单击时调用 CanExecute,但在随后的任何单击中都不会调用。此外,页面上还有其他命令随后调用 DoStuffCommand.Command.RaiseCanExecuteChanged。当这种情况发生时,CanExecute 方法实际上被称为 TWICE。
最初的开发人员通过在数据网格上连接一个右键单击事件并显式调用 RaiseCanExecuteChanged 来解决它。该解决方案的问题在于 CanExecute 每次运行两次。我已经简化了这篇文章的代码,但实际上该上下文菜单中有六个不同的命令,每个事件都会触发两次,这会导致性能问题和其他故障。
我想正确解决这个问题,以便在打开 ContextMenu 时触发一次事件,仅此而已。感觉好像可能会附加多个事件处理程序,解决方案就在这篇文章的某个地方,我已经详细研究过了。 WPF ViewModel 命令可以执行问题
这些解决方案似乎深藏在 Prism 库中,我不确定如何将其正确放入我的解决方案中。如果可能,我想避免接触或更新我们的 Prism 库。