0

I'm working on my first big WPF MVVM application now, which uses MVVM Light Toolkit in combination with Josh Smith's RelayCommand. The problem I run into is that I bound this command to an item in a ContextMenu, which keeps disabled all the time.

Here's a code snippet of the MenuItem:

<MenuItem
    Header="Verwijderen"
    Command="{StaticResource DeleteNoteCommandReference}"
    CommandParameter="{Binding}" />

Now what I've done with the commandbinding is the following: I used a class called CommandReference which I found here.

This is the commandreference itself:

<command:CommandReference
    x:Key="DeleteNoteCommandReference"
    Command="{Binding DeleteNoteCommand}" />

The reason why I've done this is because of problems with commandbinding on a ContextMenu that I noticed (caused by the fact that a ContextMenu is not part of the logical/visual tree). I found several topics about this subject on the net and in some of them I spotted the CommandReference class, which seemed a good solution to my problem. These commandbinding issues where indeed gone but it seems that the CanExecute of my command isn't recognized or something because the MenuItem keeps disabled.

In the ViewModel (which is bound to the view as its DataContext), I have the following code for the command:

    /// <summary>
    /// Command for deleting a note.
    /// </summary>
    public RelayCommand<NoteViewModel> DeleteNoteCommand {
        get;
        private set;
    }

    /// <summary>
    /// CanExecute method for the DeleteNoteCommand.
    /// </summary>
    /// <param name="note">The NoteViewModel that CanExecute needs to check.</param>
    /// <returns>True if the note can be deleted, false otherwise.</returns>
    public bool DeleteNoteCommandCanExecute(NoteViewModel note) {
        return Notes.Contains(note);
    }

    /// <summary>
    /// Creates all commands for this ViewModel.
    /// </summary>
    private void CreateCommands() {
        DeleteNoteCommand = new RelayCommand<NoteViewModel>(param => DeleteNote(param), param => DeleteNoteCommandCanExecute(param));
    }

What am I missing here to get my code functional? I thought it might have something to do with the CommandReference I'm using, but I don't know what to look for.

Really hope you guys can help!

Community
  • 1
  • 1
Thomas
  • 129
  • 1
  • 9

1 Answers1

0

Try setting a breakpoint inside of DeleteNoteCommandCanExecute and checking:

  1. if it is being called before opening the context menu and
  2. the code inside DeleteNoteCommandCanExecute doesn't throw an exception (e.g. note parameter being null)

In the first case, if it is not being called, try calling the InvalidateRequerySuggested method on the CommandManager to force a requery of the CanExecute method.

Good luck!

aKzenT
  • 7,775
  • 2
  • 36
  • 65
  • Thanks for the suggestion, but the breakpoint isn't called at all... I read about this InvalidateRequerySuggested method somewhere else, but where should I call it? When constructing my view? – Thomas Aug 21 '11 at 20:03
  • In theory you should call it when the condition changes or could possibly change. (The Notes.Contains(note)). – aKzenT Aug 21 '11 at 20:09
  • 1
    For Bug-tracking try putting it in various places (e.g. when the context menu popups) just to see if it makes a difference. But I think your problem is the command parameter, because you are using binding, but the context menu is not part of the visual tree. Strange though that the breakpoint is never hit... – aKzenT Aug 21 '11 at 20:11
  • Ok I added the CommandManager.InvalidateRequerySuggested(); call to the code that adds a note object to the Notes collection (that's where the mutation is done), but it doesn't make any difference. I noticed too that returning true instead of Notes.Contains(note) in the CanExecute method doesn't change anything too, so maybe I have to look somewhere else? – Thomas Aug 21 '11 at 20:13
  • And a breakpoint you set at the very beginning of DeleteNoteCommandCanExecute isn't getting hit even once? – aKzenT Aug 21 '11 at 20:15
  • Another thing to check is that CommandReference.Command is null for some reason. CommandReference returns false in this case for CanExecute. When is CreateCommands called? From the constructor? Try setting a breakpoint in the getter of DeleteNoteCommand – aKzenT Aug 21 '11 at 20:20
  • Ok it looks like I made a very stupid mustake, I forgot to call CreateCommands indeed ;-) Thanks very much for your help, it's working fine now! – Thomas Aug 21 '11 at 22:33