2

我继承了针对旧版本 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 库。

4

1 回答 1

0

答案根本不在于 Prism 库或 Command 框架。ContextMenu 实际上在 XAML 中被声明了两次。如上所示,第一个已附加到 DataGrid。另一个实际上在文件中更早定义为资源,并由自定义模板列中的各个控件引用。

叹息...如果其他没有经验的 WPF 开发人员遇到类似的问题,我只能建议先彻底检查您的 XAML 控件。

于 2013-01-28T23:36:50.650 回答