2
votes

I have inherited a WPF application developed against an older version of Prism (Composite Application Guidance 1.0). The general pattern in this app is to use Microsoft.Practices.Composite.Wpf.DelegateCommand in the ViewModel and avoids code-behind event handlers. It uses an MVP pattern in which the Presenter represents the ViewModel to which the XAML is bound.

I have a DataGrid with a ContextMenu and the XAML binding looks as follows:

<DataGrid.ContextMenu>
    <ContextMenu>
        <MenuItem Header="Do Stuff" Command="{Binding DoStuffCommand.Command}" />
    </ContextMenu>
</DataGrid.ContextMenu>

DoStuffCommand is actually a custom CommandBase object, which is exposed as a property on the Presenter. DoStuffCommand.Command is the actual DelegateCommand object. The DelagateCommand is constructed with Execute and CanExecute methods as defined in the Presenter (this.DoStuff, this.DoStuffCanExecute).

On the first right-click CanExecute is called but on any subsequent clicks it is not. Furthermore there are other commands on the page that subsequently call DoStuffCommand.Command.RaiseCanExecuteChanged. When that happens the CanExecute method is actually called TWICE.

The original developer solved it by wiring up a right-click event on the datagrid and explicity calling RaiseCanExecuteChanged. The problem with that solution is that CanExecute runs TWICE every time. I have simplified the code for this post but in actuality there six different commands in that context menu, all firing twice with every event, and it's causing performance problems and other glitches.

I would like to solve this properly so that the events fire once when the ContextMenu is opened and that's it. It feels as though maybe multiple event handlers are getting attached and the solution lies in somewhere in this post, which I have studied at length. WPF ViewModel Commands CanExecute issue

These solutions seem to lie deep in the Prism libraries and I'm not sure exactly how to lay it properly into my solution. I would like to avoid touching or updating our Prism libraries if possible.

1

1 Answers

0
votes

The answer did not lie in the Prism library or the Command framework at all. The ContextMenu was actually being declared twice in the XAML. The first one was attached to the DataGrid as I showed above. Another one was actually defined as a resource much earlier in the file and referenced by individual controls in the custom template columns.

Sigh...If any other inexperienced WPF developers out there experience similar issues I can only suggest a thorough examination of your XAML controls before anything else.