Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF ContextMenu itemtemplate, menuitem inside menuitem

I have the following xaml:

<ContextMenu ItemsSource="{Binding TestItems}">
     <ContextMenu.ItemTemplate>
          <DataTemplate DataType="models:TestItemModel">
              <MenuItem IsChecked="{Binding IsSelected}" Header="{Binding Header}"  />
          </DataTemplate>
     </ContextMenu.ItemTemplate>
</ContextMenu>

The TestItemModel class only consists of a IsSelected boolean property and a Header string property.

TestItems is a list of TestItemModels.

The data is binded to the contextmenu but it is reflected in the UI as a MenuItem inside a MenuItem (with the additional margins as such, making the menu very big). I can fix this by changing the MenuItem inside the DataTemplate to a TextBox, but then I cannot bind the IsSelected anymore (which I need for visualization properties).

There are a couple of questions I have regarding this:

  • Why is there a MenuItem inside a MenuItem? This doesn't make sense to me as it's not binded to a menuitem list but to a list of TestItemModels.
  • How can I resolve this?
like image 442
The Cookies Dog Avatar asked Mar 18 '15 19:03

The Cookies Dog


People also ask

Can I modify the default controltemplate for the contextmenu control?

You can modify the default ControlTemplate to give the control a unique appearance. For more information, see Create a template for a control. The ContextMenu control does not have any named parts. When you create a ControlTemplate for a ContextMenu, your template might contain an ItemsPresenter within a ScrollViewer.

How do I create a contextmenu with submenus?

Users right-click the control to make the menu appear. Typically, clicking a MenuItem opens a submenu or causes an application to carry out a command. The following examples show how to create a ContextMenu with submenus. The ContextMenu controls are attached to button controls.

How do I apply styles to a contextmenu control?

In addition to setting visual properties, you can also apply styles to parts of a control. For example, you can change the behavior of parts of the control by using properties, or you can add parts to, or change the layout of, a ContextMenu. The following examples show several ways to add styles to ContextMenu controls.

What are the parts of a menucontrol?

Menu Parts The Menucontrol does not have any named parts. When you create a ControlTemplatefor a Menu, your template might contain an ItemsPresenterwithin a ScrollViewer. (The ItemsPresenterdisplays each item in the Menu; the ScrollViewerenables scrolling within the control).


1 Answers

Because MenuItem is the container type and when it translates your view model into visual item it will wrap your template in MenuItem. In the same way ListBox will create ListBoxItem or ListView will use ListViewItem. To bind properties of the wrapper you need to use ItemContainerStyle

<ContextMenu ItemsSource="{Binding TestItems}">
   <ContextMenu.ItemContainerStyle>
      <Style TargetType="{x:Type MenuItem}">
         <Setter Property="IsChecked" Value="{Binding IsSelected}"/>
         <Setter Property="Header" Value="{Binding Header}"/>
      </Style>
   </ContextMenu.ItemContainerStyle>
</ContextMenu>

or, if you prefer, you can do it partially with ItemTemplate and ItemContainerStyle

<ContextMenu ItemsSource="{Binding TestItems}">
   <ContextMenu.ItemTemplate>
      <DataTemplate>
         <TextBlock Text="{Binding Header}"/>
      </DataTemplate>
   </ContextMenu.ItemTemplate>
   <ContextMenu.ItemContainerStyle>
      <Style TargetType="{x:Type MenuItem}">
         <Setter Property="IsChecked" Value="{Binding IsSelected}"/>
      </Style>
   </ContextMenu.ItemContainerStyle>
</ContextMenu>

In this scenario whatever is in ItemTemplate will become MenuItem.Header but IsChecked property still needs to be bound in ItemContainerStyle

like image 69
dkozl Avatar answered Sep 22 '22 23:09

dkozl