WPF- Can I Change Background Color of MenuItem and SubMenuItem When IsMouseOver Triggered Without Using Template?

1.8k Views Asked by At

enter image description here

I want to change the background color of MenuItem when IsMouseOver is triggered but without using a Template.

Could it happen?

Or should I use a Template to change background color of MenuItem when IsMouseOver is triggered?

Edit:

I try to add ControlTemplate using dhilmathy's advice, now I can change the background of the header when IsMouseOver is triggered, but how can I change the background of MenuItem? MenuItems now disappeared.

enter image description here

XAML below as:

<Menu Grid.Column="0" Background="#000d18" BorderBrush="#000d18" Cursor="Hand" Margin="28,0,0,0">
    <MenuItem Header="Test1" Width="72" Height="42" Foreground="#d8d8d8" FontSize="16">
        <MenuItem Header="Content1" Style="{StaticResource MenuItemStyle}"/>
        <MenuItem Header="Content2" Style="{StaticResource MenuItemStyle}"/>
        <MenuItem Header="Content3" Style="{StaticResource MenuItemStyle}"/>
        <MenuItem Header="Content4" Style="{StaticResource MenuItemStyle}"/>
        <MenuItem Header="Content5" Style="{StaticResource MenuItemStyle}"/>
        <MenuItem Header="Content6" Style="{StaticResource MenuItemStyle}"/>
    </MenuItem>
    <MenuItem Header="Test2" Width="72" Height="42" Foreground="#d8d8d8" FontSize="16">
        <MenuItem.Style>
            <Style TargetType="MenuItem">
                <Style.Setters>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type MenuItem}">
                                <Border Width="72" Height="42" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                                    <ContentPresenter x:Name="ContentPresenter" Content="{TemplateBinding Header}" ContentSource="Header" Margin="{TemplateBinding Padding}" VerticalAlignment="Center"/>
                                </Border>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter Property="Background" Value="#1271C8"/>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style.Setters>
            </Style>
        </MenuItem.Style>
        <MenuItem Header="Content1" Style="{StaticResource MenuItemStyle}"/>
        <MenuItem Header="Content2" Style="{StaticResource MenuItemStyle}"/>
        <MenuItem Header="Content3" Style="{StaticResource MenuItemStyle}"/>
    </MenuItem>
    <MenuItem Header="Test3" Width="72" Height="42" Foreground="#d8d8d8" FontSize="16"></MenuItem>
</Menu>

MenuItem Styles:

<Style x:Key="MenuItemStyle" TargetType="{x:Type MenuItem}">
    <Setter Property="Foreground" Value="#d8d8d8"/>
    <Setter Property="Background" Value="#414141"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="BorderBrush" Value="#414141"/>
    <Setter Property="Cursor" Value="Hand"/>
    <Setter Property="FontSize" Value="16"/>
    <Setter Property="FontFamily" Value="Arial"/>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Foreground" Value="#011627"/>
            <!--<Setter Property="Background" Value="#1271C8"/>-->
        </Trigger>
    </Style.Triggers>
</Style>
2

There are 2 best solutions below

0
On BEST ANSWER

I have already solved my question.

In order to change MenuItem's background, it must use Template.

Here is MenuItem style:

<Style x:Key="TopLevelHeaderStyle" TargetType="{x:Type MenuItem}">
        <Setter Property="Background" Value="#000d18"/>
        <Setter Property="Foreground" Value="#d8d8d8"/>
        <Setter Property="Width" Value="72"/>
        <Setter Property="Height" Value="42"/>
        <Setter Property="FontSize" Value="16"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type MenuItem}">
                    <Border x:Name="MenuItemBorder" Width="72" Height="42" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                        <Grid VerticalAlignment="Center">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <ContentPresenter Content="{TemplateBinding Header}" ContentSource="Header" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                            <Popup AllowsTransparency="True" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" Placement="Bottom" PlacementTarget="{Binding ElementName=MenuItemBorder}"
                                   HorizontalOffset="1" VerticalOffset="-1">
                                <Border BorderBrush="#414141" Background="#414141">
                                    <ScrollViewer Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}">
                                        <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                    </ScrollViewer>
                                </Border>
                            </Popup>
                        </Grid>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsHighlighted" Value="True">
                            <Setter Property="Background" Value="#1271C8"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Set Template to revise original template, and use ContentPresenter to show content and Popup to show SubMenuItem whose ItemsPresenter can show subMenuItem content. Adjust Popup's style can meet expectaion.

Besides, Trigger IsHighlighted can change MenuItem's background until clicking other position.

SubMenuItem's style can use another customized style to change.

New Style:

enter image description here

2
On

You need to modify the default ControlTemplate of MenuItem to achieve this. You can create a copy of the existing Template from Visual Studio,

VisualStudio

Default template:

<ControlTemplate x:Key="MenuItemControlTemplate1" TargetType="{x:Type MenuItem}">
    <Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" 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" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/>
            <Border x:Name="GlyphPanel" BorderBrush="#FF26A0DA" BorderThickness="1" Background="#3D26A0DA" ClipToBounds="False" HorizontalAlignment="Center" Height="22" Margin="-1,0,0,0" Visibility="Hidden" VerticalAlignment="Center" Width="22">
                <Path x:Name="Glyph" 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" Height="11" Width="10"/>
            </Border>
            <ContentPresenter x:Name="menuHeaderContainer" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="2" ContentStringFormat="{TemplateBinding HeaderStringFormat}" 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>
        <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="Glyph" 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>

You need to edit IsHighlighted Trigger to match your requirements.