Search code examples
wpfbackgroundstylesmenuitemismouseover

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


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>

Solution

  • 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