Warm tip: This article is reproduced from serverfault.com, please click

.NET MenuItem.IsSubmenuOpen = true only works the first time

发布于 2011-11-23 00:44:19

I have a ContextMenu with some sub-menus that have items (MenuItem) that can be selected. When the ContextMenu is opened, I want to recursively open the currently selected item. So, I have the following code:

    protected override void OnOpened( RoutedEventArgs e ) {
        base.OnOpened( e );
        OpenCurrentSubMenu( Items );
    }

    private static bool OpenCurrentSubMenu( ItemCollection itemCollection ) {
        foreach (MenuItem item in itemCollection) {
            if (item.IsChecked) {
                return true;
            }
            else if( OpenCurrentSubMenu( item.Items ) ) {
                item.IsSubmenuOpen = true;
                return true;
            }
        }
        return false;
    }

I also have some other code that ensures that only one item is checked.

This seems to work great the first time I select an item in a sub-menu. When I re-open the ContextMenu, the open sub-menus cascade open to the selected item:

First Drop-down

However, when I leave the context menu, and re-open it a second time, the selected menu does NOT open:

Next Drop-down

Does anyone know why and how to fix it?

Questioner
DiamondBack
Viewed
0
Jason Williams 2011-11-23 23:40:05

Three things to try:

  • When the context menu is opened, recurse over the entire hierarchy and set IsSubmenuOpen = false before you try to open any submenus. It may be that the previously open submenu is remembered and thus you're trying to tell it to have two open submenus at the same level.

  • Recurse to find the submenus that need to be opened and store them in a list. Then iterate through the list and set them so that the topmost menu is set open before its child submenu is set open. (It may be that trying to open the child when its parent is not yet open won't always work reliably).

  • Nasty brute force approach: Delete and recreate the context menu each time it is opened. It's not nice, but if you're opening a context menu you're likely to be worried about the performance implications. And it appears that it works the first time, so make every time the first time.