views:

13

answers:

1

Hi,

I templated the way items shows up in a menu, but, for an unknown reason, I am having trouble displaying the whole text in the MenuItem. Here is a screen capture of the problem: alt text

Here is the markup code I used to template it:

<ItemsPanelTemplate x:Key="SideBarItemsPanelTemplate">
    <StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
<DataTemplate x:Key="SideBarItemTemplate">
    <MenuItem Command="{Binding}" Header="{Binding Text}" Background="AliceBlue">
        <MenuItem.Icon>
            <Image Width="16" Height="16" Source="{Binding Image}"/>
        </MenuItem.Icon>
    </MenuItem>
</DataTemplate>
<Style x:Key="SideBarStyle" TargetType="{x:Type Menu}">
    <Setter Property="ItemTemplate" Value="{StaticResource SideBarItemTemplate}"/>
    <Setter Property="ItemsPanel" Value="{StaticResource SideBarItemsPanelTemplate}"/>
    <Setter Property="Background" Value="White"/>
</Style>

And to display it:

<Menu ItemsSource="{Binding Commands}" Style="{StaticResource SideBarStyle}"/>

I searched a lot, but nothing helped solving this issue. Hope I will find some help here.

Thanks.

+1  A: 

You're getting weird behavior because you have a MenuItem within a MenuItem. By setting the ItemTemplate on the Menu, you're setting the HeaderTemplate on each MenuItem. The MenuItem will render its normal template, and where the header text would normally be placed it will have an entire other MenuItem. I think the space you see is the space reserved for the InputGestureText in the outer MenuItem.

Instead, you want to set an ItemContainerStyle. This will let you set properties on the MenuItems created by the Menu. There is one trick you need to use so that you can create a separate Image object for each MenuItem. By default, objects included in a Style will be shared, and you will get one Image object shared by every MenuIte, but if you put them in a separate resource dictionary you can mark them as not shared. See this issue on Connect and the linked workaround.

Something like this:

<Style x:Key="SideBarStyle" TargetType="{x:Type Menu}">
    <Setter Property="ItemsPanel" Value="{StaticResource SideBarItemsPanelTemplate}"/>
    <Setter Property="Background" Value="White"/>
    <Setter Property="ItemContainerStyle">
        <Setter.Value>
            <Style TargetType="MenuItem">
                <Style.Resources>
                    <ResourceDictionary Source="Icon.xaml"/>
                </Style.Resources>
                <Setter Property="Command" Value="{Binding}"/>
                <Setter Property="Header" Value="{Binding Text}"/>
                <Setter Property="Background" Value="AliceBlue"/>
                <Setter Property="Icon" Value="{StaticResource Icon}"/>
            </Style>
        </Setter.Value>
    </Setter>
</Style>

Where Icon.xaml contains:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <Image x:Key="Icon" x:Shared="False" Width="16" Height="16" Source="{Binding Image}"/>
</ResourceDictionary>
Quartermeister
Well done! This works pretty well. But it made me realize that this Style behavior can result in a kind of really strange side-effect. As this is a behavior related to Style it seems that I do not have other solution. I do not really appreciate the fact that I will need a separated resource for this so I just added the Image resource in my current ResourceDictionary.
Ucodia