Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF MenuItem Header and HeaderTemplate

I want to bind a list of KeyValuePair to a list of MenuItems. I thought I should use MenuIten.HeaderTemplate, but it didn't work. I only got blank headers.

            <MenuItem 
                Header="Template" 
                ItemsSource="{Binding Path=Samples}">
                <MenuItem.ItemTemplate>
                    <DataTemplate>
                        <MenuItem>
                            <MenuItem.HeaderTemplate>
                                <DataTemplate>
                                    <StackPanel Orientation="Horizontal">
                                        <TextBlock Text="{Binding Path=Key}" FontWeight="Bold"/>
                                        <TextBlock Text="{Binding Path=Value}" FontStyle="Italic" Margin="5,0,0,0"/>
                                    </StackPanel>
                                </DataTemplate>
                            </MenuItem.HeaderTemplate>                            </MenuItem>
                    </DataTemplate>
                </MenuItem.ItemTemplate>
            </MenuItem>

Then I replaced MenuItem.HeaderTemplate with MenuItem.Header, it worked.

            <MenuItem 
                Header="Template" 
                ItemsSource="{Binding Path=Samples}">
                <MenuItem.ItemTemplate>
                    <DataTemplate>
                        <MenuItem>
                            <MenuItem.Header>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="{Binding Path=Key}" FontWeight="Bold"/>
                                    <TextBlock Text="{Binding Path=Value}" FontStyle="Italic" Margin="2,0,0,0"/>
                                </StackPanel>
                            </MenuItem.Header>
                        </MenuItem>
                    </DataTemplate>
                </MenuItem.ItemTemplate>
            </MenuItem>

Can anyone explain to me why HeaderTemplate doesn't work here?

like image 941
treehouse Avatar asked May 22 '09 18:05

treehouse


3 Answers

Micah is correct. In the first approach I told the menu item how to template itself but never told it what data it binds to! The following works:

            <MenuItem 
            Header="Template" 
            ItemsSource="{Binding Path=Samples}">
            <MenuItem.ItemTemplate>
                <DataTemplate>
                    <MenuItem Header="{Binding}">
                        <MenuItem.HeaderTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="{Binding Path=Key}" FontWeight="Bold"/>
                                    <TextBlock Text="{Binding Path=Value}" FontStyle="Italic" Margin="5,0,0,0"/>
                                </StackPanel>
                            </DataTemplate>
                        </MenuItem.HeaderTemplate>
                     </MenuItem>
                </DataTemplate>
            </MenuItem.ItemTemplate>
        </MenuItem>
like image 134
treehouse Avatar answered Nov 18 '22 11:11

treehouse


Because the HeaderTemplate doesn't have access to the data being bound to the menu item.

like image 36
Micah Avatar answered Nov 18 '22 10:11

Micah


The purpose of the Template is to add some elements to the VisualTree. DataTemplate is used for the sub-items ([Sub]MenuItem, ListBoxItem in ListBox, and so on) and is applied to the items holder, it is contrary to the ControlTemplate, wich is applied to the control itself. What you actually did by this

<MenuItem 
            Header="Template" 
            ItemsSource="{Binding Path=Samples}">
            <MenuItem.ItemTemplate>
                <DataTemplate>
                       ....
   </DataTemplate>
  </MenuItem.ItemTemplate>
</MenuItem>

is telling "I want take MenuItem content and Insert the data, wich must be visualized". And then insert this insted dots:

 <MenuItem Header="{Binding}">... </MenuItem>

So you are inserting additional menu item to the currently iterating menu item. I can't see the point. Next is more clear:

 <MenuItem Header="Template" ItemsSource="{Binding Samples}">
         <MenuItem.Resources>
            <Style TargetType="{x:Type MenuItem}">
               <Setter Property="Command" Value="{Binding SomeCommand}" />
            </Style>            
        </MenuItem.Resources>
       <MenuItem.ItemTemplate>
          <DataTemplate>
              <TextBlock Text="{Binding Name}" />
          </DataTemplate>             
       </MenuItem.ItemTemplate>
    </MenuItem>
like image 1
Artur A Avatar answered Nov 18 '22 11:11

Artur A