4

My application contains a TreeView which supports a set of commands, but the commands might move around between menus, only appear on some menus and not others, be shared across multiple menus, etc.

I know the set of all commands that I support at compile time, so in theory I can define a <MenuItem> resource with an x:Key attribute for each of them in my <TreeView.Resources> section. However, for any given node that is clicked, which menu items that appear can only be determined at runtime. I can bind ContextMenu.ItemsSource to something in my application that returns a MenuItem[], but in order to build this array, I would then need to access the MenuItems that were defined statically back in the XAML file.

Am I doing this all wrong? Or is there a way to do what I want?

Zachary Turner
  • 738
  • 4
  • 24

2 Answers2

6

Bind your ContextMenu.ItemsSource not to a MenuItem[] but a ObservableCollection < YourMenuClass >. YourMenuClass should contain the header and other parameters you want to bind to, maybe a command. Then use a template to generate your menuitems.

   <ContextMenu ItemsSource="{Binding MenuItemList}">
            <ContextMenu.ItemTemplate>
                <DataTemplate>
                    <MenuItem Header="{Binding Path=Name}" Command="{Binding MyCommand}" />
                </DataTemplate>
            </ContextMenu.ItemTemplate>
    </ContextMenu>
Chrille
  • 1,435
  • 12
  • 26
  • When I do this the MenuItem looks funny. It's elongated, with a significant amount of padding on the left and right side of the MenuItem, and I'm not sure why. Here's an example of what I get with 2 menu items added. http://i.imgur.com/O8is6O1.png Note that the darker highlight rectangle is particularly odd. It goes away if I hover the mouse outside of the bounds of the darker rectangle. It's like the ContextMenu itself doesn't know how to size correctly. – Zachary Turner Apr 03 '14 at 22:08
  • 2
    For some reason I had to use a in the , and then it works. I guess otherwise it puts a MenuItem inside of another MenuItem? Not sure how it works behind the scenes, but changing up there to fixes it. Although then I have to put the Command somewhere else. In this case, I got it working by using a on a Style for TargetType="MenuItem" – Zachary Turner Apr 03 '14 at 22:51
  • Ok, I'm sorry, but I can't explain this behavior. – Chrille Apr 05 '14 at 19:55
  • See [this answer](https://stackoverflow.com/a/29130774/12342238) for how to solve the menu item inside menu item problem. – JonasH Feb 15 '21 at 13:41
2

Instead of using an Itemtemplate, provide ItemContainer style for context menu. In this way you can avoid the problem of having a Menu item inside another as mentioned in the above comment.

       `<ContextMenu.ItemContainerStyle>
            <Style TargetType="{x:Type MenuItem}">
                <Setter Property="Header" Value="{Binding Name}"/>
            </Style>
        </ContextMenu.ItemContainerStyle>`
Vimal P
  • 21
  • 5