C# WPF Menu Item Style let the Header disappear

I have set a style for my MenuItems which looks like the following

App.xaml

<Style x:Key="MenuItemHover" TargetType="MenuItem">
        <Setter Property="Width" Value="50"></Setter>
        <Setter Property="FontFamily" Value="Calibri"></Setter>
        <Setter Property="Template">

            <Setter.Value>
                <ControlTemplate TargetType="MenuItem">

                    <Border x:Name="border"
                            Background="#282828"
                            >

                    </Border>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="border" Property="Background" Value="Gray"></Setter>

                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

MainWindow.xaml

<Menu x:Name="Menu_Dropdown" Width="150" Background="#282828" Foreground="White" HorizontalAlignment="Left" Grid.Column="0" Grid.ColumnSpan="2" Height="25" VerticalAlignment="Top">
        <MenuItem x:Name="MenuItem_User" Height="25" Header="Nutzer" Style="{DynamicResource MenuItemHover}"></MenuItem>
        <MenuItem x:Name="MenuItem_Kasse" Header="Kasse" Style="{DynamicResource MenuItemHover}"></MenuItem>
        <MenuItem x:Name="MenuItem_Design" Header="Design" Style="{DynamicResource MenuItemHover}"></MenuItem>
    </Menu>

When I use my style "MenuItemHover" it let the text disappear. The rest is working fine. (so the hover effect itself - it's changing the color when I move my mouse over)

Without using the style the header is getting showed normally.

Answers


There are a couple of things to make this code better, let's take a look one by one.

First of all, when you override the template, you need to know that you're not extending, but rather rewrite it; therefore you need to add the "obvious" parts as well, not just the new ones. As Anton says, you need at least one control to display the text itself. See his answer for an example.

Secondly, if you want to use the same style for every MenuItem, it is better to define the Style without a key. That way that's going to be the default style for MenuItems and it will be applied to all of them unless you say explicitly otherwise. (You don't need to add Style="{DynamicResource MenuItemHover}" to every MenuItem tag. Keep in mind that there is a hierarchy of applying styles. For example if you set the font size to 15 in the style, but then you add FontSize="50" to one of the MenuItems explicitly that MenuItem will use the value 50. See more about it here)

Last, but not least I think a good way to do this kind of changes in the styles is opening up Blend, select the control, then create a copy of the original template:

and customize that copy. (As you can see below this is just the ControlTemplate, you need to put this into a style) This way you can be sure you won't lose anything that is there originally. Example (MenuItem ControlTemplate):

    <ControlTemplate x:Key="MenuItemControlTemplate1" TargetType="{x:Type MenuItem}">
        <Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
            <Grid VerticalAlignment="Center">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/>
                <Path x:Name="GlyphPanel" Data="F1M10,1.2L4.7,9.1 4.5,9.1 0,5.2 1.3,3.5 4.3,6.1 8.3,0 10,1.2z" Fill="#FF212121" FlowDirection="LeftToRight" Margin="3" Visibility="Collapsed" VerticalAlignment="Center"/>
                <ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="1" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
            </Grid>
        </Border>
        <ControlTemplate.Triggers>
            <Trigger Property="Icon" Value="{x:Null}">
                <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
            </Trigger>
            <Trigger Property="IsChecked" Value="True">
                <Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
                <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
            </Trigger>
            <Trigger Property="IsHighlighted" Value="True">
                <Setter Property="Background" TargetName="templateRoot" Value="#3D26A0DA"/>
                <Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/>
            </Trigger>
            <Trigger Property="IsEnabled" Value="False">
                <Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="#FF707070"/>
                <Setter Property="Fill" TargetName="GlyphPanel" Value="#FF707070"/>
            </Trigger>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsHighlighted" Value="True"/>
                    <Condition Property="IsEnabled" Value="False"/>
                </MultiTrigger.Conditions>
                <Setter Property="Background" TargetName="templateRoot" Value="#0A000000"/>
                <Setter Property="BorderBrush" TargetName="templateRoot" Value="#21000000"/>
            </MultiTrigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

The relevant part in your case is:

<Trigger Property="IsHighlighted" Value="True">
    <Setter Property="Background" TargetName="templateRoot" Value="#3D26A0DA"/>
    <Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/>
</Trigger>

You can change the background color here to achieve what you want (I changed it to Red to see it better):

You may want to change the BorderBrush color as well.


Your template should contains ContentPresenter

<Border x:Name="border"Background="#282828" >
     <ContentPresenter Content="{TemplateBinding Header}"/>
</Border>

In native template of MenuItem used ContentPresenter and set ContentSource="Header"

<ControlTemplate x:Key="{ComponentResourceKey ResourceId=SubmenuItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}" TargetType="{x:Type MenuItem}">
    <Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Height="22" SnapsToDevicePixels="true">
        <Grid Margin="-1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition MinWidth="22" SharedSizeGroup="MenuItemIconColumnGroup" Width="Auto"/>
                <ColumnDefinition Width="13"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="30"/>
                <ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
                <ColumnDefinition Width="20"/>
            </Grid.ColumnDefinitions>
            <ContentPresenter x:Name="Icon" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/>
            <Border x:Name="GlyphPanel" BorderBrush="{StaticResource MenuItem.Highlight.Border}" BorderThickness="1" Background="{StaticResource MenuItem.Highlight.Background}" HorizontalAlignment="Center" Height="22" Margin="-1,0,0,0" Visibility="Hidden" VerticalAlignment="Center" Width="22">
                <Path x:Name="Glyph" Data="{StaticResource Checkmark}" Fill="{StaticResource MenuItem.Selected.Glyph}" FlowDirection="LeftToRight" Height="11" Width="9"/>
            </Border>
            <!-- ContentPresenter which showing MenuItem.Header -->
            <ContentPresenter x:Name="menuHeaderContainer" Grid.Column="2" ContentSource="Header" HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/>
            <TextBlock x:Name="menuGestureText" Grid.Column="4" Margin="{TemplateBinding Padding}" Opacity="0.7" Text="{TemplateBinding InputGestureText}" VerticalAlignment="Center"/>
        </Grid>
    </Border>
    <ControlTemplate.Triggers>
        ...
    </ControlTemplate.Triggers>
</ControlTemplate>

Need Your Help

How to use create event on a jQuery dialog in following scenario?

javascript jquery jquery-ui-dialog hidden-field jquery-dialog

I've have following dialog pop-up HTML which is hidden initially when page loads(look line style="display:none;" in div):

Detect significantly distinct image from a set, such as with OpenCV or SimpleCV

image opencv computer-vision motion-detection simplecv

I have still images captured over the course of one night by a webcam. The majority are identical, since the lighting in the images is uniform. However, some are significantly different from the re...