views:

4453

answers:

3

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?

+2  A: 

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

Micah
Thanks. How do I access the data in HeaderTemplate in XAML then? Doesn't MenuItem.Template inherit the DataContext from its parent, the Menu?
Kai Wang
Apparently I post this question when I didn't know too much about WPF. Thanks Micah and sorry for the late acceptance.
Kai Wang
A: 

The HeaderTemplate definition should be a DataTemplate, not direct UI content :

...
<MenuItem.HeaderTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Path=Key}" FontWeight="Bold"/>
            <TextBlock Text="{Binding Path=Value}" FontStyle="Italic" Margin="2,0,0,0"/>
        </StackPanel>
    </DataTemplate>
</MenuItem.HeaderTemplate>
...
Thomas Levesque
Sorry, I missed the DataTemplate when posting the question. Without DataTemplate the code doesn't compile. I just updated my question. The menu item headers don't show up with DataTemplate.
Kai Wang
+3  A: 

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>
Kai Wang