Using a DataTemplate for a MenuItem causes extra space on the left side to appear?

djcouchycouch picture djcouchycouch · Aug 21, 2009 · Viewed 14.4k times · Source

Whenever I attach a DataTemplate to a MenuItem, each generated menu item gets an extra space on the left side. This extra space looks as wide as the space reserved for the check, which I use. Building a menu manually without a DataTemplate doesn't add this extra space. As an extra wrinkle, if I click on this extra space the menu item goes away but no click event is generated. I don't know why it's adding this extra space. Any ideas?

my xaml code couldn't be more simpler:

Menu with the described extra spaces:

<Menu>
    <MenuItem Header="Enemies" ItemsSource="{Binding AvailableEnemyClasses}">
        <MenuItem.ItemTemplate>
            <DataTemplate>
                <MenuItem Header="{Binding}">
                </MenuItem>
            </DataTemplate>
        </MenuItem.ItemTemplate>
    </MenuItem>
</Menu>

Menu without extra spaces:

<Menu>
    <MenuItem Header="Utilities" >
        <MenuItem Header="Enemy01"/>
        <MenuItem Header="Enemy02"/>
        <MenuItem Header="Enemy03"/>
    </MenuItem>
</Menu>

Answer

Kent Boogaart picture Kent Boogaart · Aug 21, 2009

It's because the visual tree produced by your DataTemplate will be wrapped in a container - in this case, a MenuItem. Therefore, you actually have a MenuItem within a MenuItem, which explains the extra space and the lack of interactivity. There's no need to include the MenuItem in your ItemTemplate.

Your example might instead be written as:

<Menu>
    <MenuItem Header="Enemies" ItemsSource="{Binding AvailableEnemyClasses}">
        <MenuItem.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding}"/>
            </DataTemplate>
        </MenuItem.ItemTemplate>
    </MenuItem>
</Menu>

Or, perhaps more succinctly:

<Menu>
    <MenuItem Header="Enemies" ItemsSource="{Binding AvailableEnemyClasses}">
        <MenuItem.ItemContainerStyle>
            <Style TargetType="MenuItem">
                <Setter Property="Header" Value="{Binding}"/>
                <Setter Property="IsChecked">
                    <Setter.Value>
                        <MultiBinding Converter="{StaticResource YourConverter}">
                            <Binding .../>
                            <Binding .../>
                        </MultiBinding>
                    </Setter.Value>
                </Setter>
            </Style>
        </MenuItem.ItemContainerStyle>
    </MenuItem>
</Menu>