我继承了针对旧版Prism(Composite Application Guidance 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。
原始开发人员通过在datagrid上连接右键单击事件并明确调用RaiseCanExecuteChanged来解决它。该解决方案的问题是CanExecute每次运行TWICE。我已经简化了这篇文章的代码,但实际上在该上下文菜单中有六个不同的命令,每个事件都会触发两次,这会导致性能问题和其他故障。
我想正确解决这个问题,以便在打开ContextMenu时触发一次事件,就是这样。感觉好像可能有多个事件处理程序被附加,并且解决方案位于这篇文章的某个地方,我已经详细研究过了。 WPF ViewModel Commands CanExecute issue
这些解决方案似乎深入到Prism库中,我不确定如何将其正确地放入我的解决方案中。如果可能的话,我想避免接触或更新我们的Prism库。
答案 0 :(得分:0)
答案不在于Prism库或Command框架。 ContextMenu实际上是在XAML中声明了两次。如上所示,第一个附加到DataGrid。另一个实际上被定义为文件中较早的资源,并由自定义模板列中的各个控件引用。
叹息......如果其他任何没有经验的WPF开发人员遇到类似的问题,我只能建议您先对XAML控件进行全面检查。