In my WPF application I have a sort of node graph. I have added a ContextMenu
to these nodes, which appears when I right-click on stuff and so on.
The commands in the context menu come from a Service (Microsoft.Practices.ServiceLocation.ServiceLocator
) with DelegateCommands
, and those commands are updated with RaiseCanExecuteChanged()
. The node that was right-clicked on is passed to this command service, which is used in the various CanExecute
methods for the commands.
The nodes all have some properties which are used in these conditions, like whether it can be renamed or deleted, etc.
private void ContextMenu_ContextMenuOpening(object sender, RoutedEventArgs e) {
ServiceLocator.Current.GetInstance<IMenuCommandService>().ReloadICommandConditions();
}
in IMenuCommandService:
public void ReloadICommandConditions() {
((DelegateCommand<Node>) MyCommand).RaiseCanExecuteChanged();
}
My ContextMenu (inside a DataTrigger
& Setter
):
<ContextMenu>
<MenuItem Header="Rename"
Command="{Binding MenuCommandService.Rename}"
CommandParameter="{Binding Node}" />
<MenuItem Header="Delete"
Command="{Binding MenuCommandService.Delete}"
CommandParameter="{Binding Node}" />
...
</ContextMenu>
My problem is that when I right click one of these nodes, the context menu that is displayed looks like it was configured for the previous node selected. Like if I right-click a deleteable node and then a non-deleteable node, the "Delete" command on the context menu will still be clickable. (If I then right-click the non-deleteable node, the context menu will then be correct and the "Delete" command is greyed out.)
So it looks like there's some sort of delay from when the changes made after RaiseCanExecuteChanged()
is actually there for the contextmenu to "pick up". I could do a crude fix and only show the contextmenu after they have been updated (i.e. their CanExecute
methods have been called), but I'd like to keep the two parts relatively separate.
Is there something obvious I'm missing, am I going about this in the wrong way, or does anyone have any other suggestions?
Thanks
<MenuItem Header="Rename" Command="{Binding MenuCommandService.Rename}" CommandParameter="{Binding Node}" />
. This parameter is being supplied correctly when the actual items in the contextmenu are clicked, but they aren't when it's first opened. – Pyritie