1

I'm creating a WPF app and have a system tray icon with a context menu. For the menu items I want to use WPF commands but when I assign them they are always greyed out even though the (same) commands are enabled in other places.

MenuItem menuItem = new MenuItem();
menuItem.Header = "Exit";
menuItem.Command = CustomCommands.ExitApplication;
Systray.AddMenuItem(menuItem);

It works fine when I assign click events and I have tried to create a CanExecute method for the command which always sets CanExecute to true, but that doesn't help either. Anyone got an idea why the menu items are disabled?


Update: As suggested, I added a command binding to the context menu. This had the effect that it works but only after you have clicked on the menu, i.e., at first the menu items are greyed out but once you click somewhere on the menu the options become enabled.

To solve this problem I called the following, after I added the menu items to the context menu:

CommandManager.InvalidateRequerySuggested();
Morten Christiansen
  • 19,002
  • 22
  • 69
  • 94

3 Answers3

3

Of the top of my head I'd guess you have to add a CommandBinding to the Menu or systray so that your command gets handled. Although I think if that were the case it would be enabled by default.

Bryan Anderson
  • 15,969
  • 8
  • 68
  • 83
2

Yea I've seen this occur. Sometimes you have to tell the WPF CommandManager system to rerun the CanExecute methods. Try calling this once the ContextMenu is loaded: CommandManager.InvalidateQuerySuggested();

biju
  • 17,554
  • 10
  • 59
  • 95
Szymon Rozga
  • 17,971
  • 7
  • 53
  • 66
0

I had a similar issue. I feel my solution it's a bit of a hack, but I could really not get around this problem. I'm using a custom DelegateCommand implementation, and ebabling/disabling buttons and menu items works except for items in context menus. So, what I did was to handle the ContextMenuOpening event, then store the Items in a temp variable, call the Clear method in the ContextMenu and re-add the items right after. Works like a charm, but like I said, feels "hacky". It goes something like this:

    private void ContextMenu_ContextMenuOpening (object sender, System.ComponentModel.CancelEventArgs e)
    {
        // HACK: For some reason items need to be removed and added back so that the command enablement requery works.
        var menu = sender as ContextMenu;
        if (menu == null) return;

        var menuItems = menu.Items.ToArray();
        menu.Items.Clear();
        foreach (var menuItem in menuItems)
            menu.Items.Add(menuItem);
    }
Mario
  • 659
  • 7
  • 12