Question

I'm dynamically creating a context menu and the menu items have children. The first time around the submenus appear, but on the second and there after only the parent menus show. The child submenu are in the collection that is bound to the context menu they just don't appear.

VMMenuItems is a property in my view model and is

ObservableCollection<MenuItemViewModel>

Every time the data in the Listview changes VMMenuItems is totally rebuilt. A sub menu is just adding another MenuItemViewModel to an existing MenuItemViewModel's Children. Any ideas as to how to make the submenus work every time?

The code

<Window.Resources>        
    <HierarchicalDataTemplate DataType="{x:Type local:MenuItemViewModel}"
                              ItemsSource="{Binding Path=Children}">
        <ContentPresenter Content="{Binding Path=MenuText}" />
    </HierarchicalDataTemplate>
</Window.Resources>

 <ListView.ContextMenu>
       <ContextMenu ItemsSource="{Binding Path=VMMenuItems>
          <ContextMenu.ItemContainerStyle>
              <Style TargetType="{x:Type MenuItem}">                                    
                 <Setter Property="Command" Value="{Binding Command}"/>
                  <Setter Property="CommandParameter" Value="{Binding MenuText}"/> 
                            </Style>
                        </ContextMenu.ItemContainerStyle>
                    </ContextMenu>                       
                </ListView.ContextMenu>

public class MenuItemViewModel : ViewModel
{  
    public MenuItemViewModel()
    {
        Children = new ObservableCollection<MenuItemViewModel>();
    }


    private string _menuText;
    public string MenuText
    {

        get { return _menuText; }

        set
        {
            _menuText = value;
            OnPropertyChanged("MenuText");
        }
    }


    private bool _isEnabled;
    public bool IsEnabled
    {
        get { return _isEnabled; }

        set
        {
            _isEnabled = value;
            OnPropertyChanged("IsEnabled");
        }
    }


    private ICommand _command;
    public ICommand Command
    {
        get { return _command; }

        set
        {
            _command = value;
            OnPropertyChanged("Command");
        }
    }

    private ObservableCollection<MenuItemViewModel> _children;
    public ObservableCollection<MenuItemViewModel> Children
    {
        get { return _children; }

        set
        {
            _children = value;
            OnPropertyChanged("Children");
        }
    }
Was it helpful?

Solution

I had to not use a HierarchicalDataTemplate and put it all here in ContextMenu.ItemContainerStyle. I'm not sure why my other way didn't work( well it worked the 1st time but not any others). Maybe someone else could tell me why it doesn't work...

<ContextMenu.ItemContainerStyle>
  <Style TargetType="{x:Type MenuItem}">
   <Setter Property="Header" Value="{Binding MenuText}"/>
   <Setter Property="ItemsSource" Value="{Binding Path=Children}"/>
   <Setter Property="Command" Value="{Binding Command}"/>
   <Setter Property="CommandParameter" Value="{Binding MenuText}"/>
  </Style>
 </ContextMenu.ItemContainerStyle>

OTHER TIPS

I'm still new to this myself and I don't know for sure without testing it or exactly why, but I believe it has to do with replacing the Children collection with an entirely new collection. I think that would require rebinding the collection. It would be better for items to be added/removed from the existing collection. This would trigger the appropriate binding notifications. Right now, the binding is to a particular instance of that collection which is getting replaced on the Children.set call. Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top