c# - 如何在 WPF 中更改 MouseOver 上的 MenuItem 的背景

标签 c# wpf menu menuitem

阅读了很多资料并提出了很多问题,我终于在 WPF 中为我的 Menu/MenuItem 组合了一个新样式。

但是当单个子菜单高亮显示时,我想更改它的背景和边框。

在下图中,我希望将蓝色背景更改为黄色!

enter image description here

到目前为止,这是完整的工作代码:

<Window x:Class="WpfApplication12.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>

        <LinearGradientBrush x:Key="DarkBrush" StartPoint="0.5,0" EndPoint="0.5,1">
            <GradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop Color="#939393" Offset="0.0"/>
                    <GradientStop Color="#717171" Offset="0.05"/>
                    <GradientStop Color="#606060" Offset="1.0"/>
                </GradientStopCollection>
            </GradientBrush.GradientStops>
        </LinearGradientBrush>

        <LinearGradientBrush x:Key="Clicked" StartPoint="0.5,0" EndPoint="0.5,1">
            <GradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop Color="#363636" Offset="0.0"/>
                    <GradientStop Color="#393939" Offset="1.0"/>
                </GradientStopCollection>
            </GradientBrush.GradientStops>
        </LinearGradientBrush>


        <Style x:Key="{x:Type Menu}" TargetType="Menu">
            <Setter Property="OverridesDefaultStyle" Value="True"/>
            <Setter Property="SnapsToDevicePixels" Value="True"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Menu">
                        <Border x:Name="MainMenu" Background="#535353">
                            <StackPanel ClipToBounds="True" Orientation="Horizontal" IsItemsHost="True"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <ControlTemplate x:Key="MenuItemControlTemplate1" TargetType="{x:Type MenuItem}">
            <Border x:Name="templateRoot" 
                    BorderBrush="#535353" 
                    CornerRadius="3" 
                    BorderThickness="1" 
                    Background="{TemplateBinding Background}" 
                    SnapsToDevicePixels="True">
                <Grid VerticalAlignment="Center">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>


                    <ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="1" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    <Popup x:Name="PART_Popup"  AllowsTransparency="True" Focusable="False" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Placement="Bottom">
                        <Border x:Name="SubMenuBorder" BorderBrush="#595959" BorderThickness="1" Background="#3A3A3A" Padding="2">
                            <ScrollViewer x:Name="SubMenuScrollViewer" Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}">
                                <Grid RenderOptions.ClearTypeHint="Enabled">
                                    <Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
                                        <Rectangle x:Name="OpaqueRect" Fill="{Binding Background, ElementName=SubMenuBorder}" Height="{Binding ActualHeight, ElementName=SubMenuBorder}" Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/>
                                    </Canvas>
                                    <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle"/>
                                </Grid>
                            </ScrollViewer>
                        </Border>
                    </Popup>
                </Grid>
            </Border>
            <ControlTemplate.Triggers>
                <Trigger Property="IsSuspendingPopupAnimation" Value="True">
                    <Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
                </Trigger>

                <Trigger Property="IsHighlighted" Value="True">
                    <Setter Property="Background" TargetName="templateRoot" Value="{StaticResource DarkBrush}"/>
                    <Setter Property="BorderBrush" TargetName="templateRoot" Value="#2C2C2C"/>
                    <Setter Property="BorderThickness" TargetName="templateRoot" Value="1"></Setter>
                </Trigger>

                <Trigger Property="CanContentScroll" SourceName="SubMenuScrollViewer" Value="False">
                    <Setter Property="Canvas.Top" TargetName="OpaqueRect" Value="{Binding VerticalOffset, ElementName=SubMenuScrollViewer}"/>
                    <Setter Property="Canvas.Left" TargetName="OpaqueRect" Value="{Binding HorizontalOffset, ElementName=SubMenuScrollViewer}"/>
                </Trigger>
                <Trigger Property="IsKeyboardFocusWithin" Value="True">
                    <Setter TargetName="templateRoot" Property="Background" Value="{StaticResource Clicked}" />
                    <Setter Property="Header" Value="Test" />
                    <Setter Property="BorderBrush" Value="#2C2C2C"></Setter>
                    <Setter Property="BorderThickness" Value="1"></Setter>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>

    </Window.Resources>
    <Grid Background="#535353">
        <Menu Width="100" Height="22" Margin="10, 10, 5, 5" HorizontalAlignment="Left" Background="White" VerticalAlignment="Top">
            <MenuItem Header="_File" Name="mm" Template="{DynamicResource MenuItemControlTemplate1}">
                <MenuItem Header="_New"/>
                <MenuItem Header="_Open"/>
                <MenuItem Header="_Close"/>
            </MenuItem>
            <MenuItem Header="_Edit" Template="{DynamicResource MenuItemControlTemplate1}">
                <MenuItem Header="_Copy"/>
                <MenuItem Header="_Cut"/>
                <MenuItem Header="_Paste"/>
            </MenuItem>
        </Menu>
    </Grid>
</Window>

最佳答案

再做一个模板。这是一个背景为黄色、边框为橙色和文本为黑色的。

查看 MenuItem ControlTemplate 2,IsHighlighted 触发器。

<Window x:Class="WpfApplication12.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>

    <LinearGradientBrush x:Key="DarkBrush" StartPoint="0.5,0" EndPoint="0.5,1">
        <GradientBrush.GradientStops>
            <GradientStopCollection>
                <GradientStop Color="#939393" Offset="0.0"/>
                <GradientStop Color="#717171" Offset="0.05"/>
                <GradientStop Color="#606060" Offset="1.0"/>
            </GradientStopCollection>
        </GradientBrush.GradientStops>
    </LinearGradientBrush>

    <LinearGradientBrush x:Key="Clicked" StartPoint="0.5,0" EndPoint="0.5,1">
        <GradientBrush.GradientStops>
            <GradientStopCollection>
                <GradientStop Color="#363636" Offset="0.0"/>
                <GradientStop Color="#393939" Offset="1.0"/>
            </GradientStopCollection>
        </GradientBrush.GradientStops>
    </LinearGradientBrush>


    <Style x:Key="{x:Type Menu}" TargetType="Menu">
        <Setter Property="OverridesDefaultStyle" Value="True"/>
        <Setter Property="SnapsToDevicePixels" Value="True"/>
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Menu">
                    <Border x:Name="MainMenu" Background="#535353">
                        <StackPanel ClipToBounds="True" Orientation="Horizontal" IsItemsHost="True"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <ControlTemplate x:Key="MenuItemControlTemplate1" TargetType="{x:Type MenuItem}">
        <Border x:Name="templateRoot" 
                BorderBrush="#535353" 
                CornerRadius="3" 
                BorderThickness="1" 
                Background="{TemplateBinding Background}" 
                SnapsToDevicePixels="True">
            <Grid VerticalAlignment="Center">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>


                <ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="1" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                <Popup x:Name="PART_Popup"  AllowsTransparency="True" Focusable="False" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Placement="Bottom">
                    <Border x:Name="SubMenuBorder" BorderBrush="#595959" BorderThickness="1" Background="#3A3A3A" Padding="2">
                        <ScrollViewer x:Name="SubMenuScrollViewer" Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}">
                            <Grid RenderOptions.ClearTypeHint="Enabled">
                                <Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
                                    <Rectangle x:Name="OpaqueRect" Fill="{Binding Background, ElementName=SubMenuBorder}" Height="{Binding ActualHeight, ElementName=SubMenuBorder}" Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/>
                                </Canvas>
                                <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle"/>
                            </Grid>
                        </ScrollViewer>
                    </Border>
                </Popup>
            </Grid>
        </Border>
        <ControlTemplate.Triggers>
            <Trigger Property="IsSuspendingPopupAnimation" Value="True">
                <Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
            </Trigger>

            <Trigger Property="IsHighlighted" Value="True">
                <Setter Property="Background" TargetName="templateRoot" Value="{StaticResource DarkBrush}"/>
                <Setter Property="BorderBrush" TargetName="templateRoot" Value="#2C2C2C"/>
                <Setter Property="BorderThickness" TargetName="templateRoot" Value="1"></Setter>
            </Trigger>

            <Trigger Property="CanContentScroll" SourceName="SubMenuScrollViewer" Value="False">
                <Setter Property="Canvas.Top" TargetName="OpaqueRect" Value="{Binding VerticalOffset, ElementName=SubMenuScrollViewer}"/>
                <Setter Property="Canvas.Left" TargetName="OpaqueRect" Value="{Binding HorizontalOffset, ElementName=SubMenuScrollViewer}"/>
            </Trigger>
            <Trigger Property="IsKeyboardFocusWithin" Value="True">
                <Setter TargetName="templateRoot" Property="Background" Value="{StaticResource Clicked}" />
                <Setter Property="Header" Value="Test" />
                <Setter Property="BorderBrush" Value="#2C2C2C"></Setter>
                <Setter Property="BorderThickness" Value="1"></Setter>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

    <ControlTemplate x:Key="MenuItemControlTemplate2" 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="BorderBrush" TargetName="templateRoot" Value="Orange"/>
                <Setter Property="Background" TargetName="templateRoot" Value="Yellow"/>
                <Setter Property="TextBlock.Foreground" TargetName="menuHeaderContainer" Value="Black" />
            </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>

</Window.Resources>
<Grid Background="#535353">
    <Menu Width="100" Height="22" Margin="10, 10, 5, 5" HorizontalAlignment="Left" Background="White" VerticalAlignment="Top">
        <MenuItem Header="_File" Name="mm" Template="{DynamicResource MenuItemControlTemplate1}">
            <MenuItem Header="_New" Template="{DynamicResource MenuItemControlTemplate2}" />
            <MenuItem Header="_Open" Template="{DynamicResource MenuItemControlTemplate2}" />
            <MenuItem Header="_Close" Template="{DynamicResource MenuItemControlTemplate2}" />
        </MenuItem>
        <MenuItem Header="_Edit" Template="{DynamicResource MenuItemControlTemplate1}">
            <MenuItem Header="_Copy" Template="{DynamicResource MenuItemControlTemplate2}" />
            <MenuItem Header="_Cut" Template="{DynamicResource MenuItemControlTemplate2}" />
            <MenuItem Header="_Paste" Template="{DynamicResource MenuItemControlTemplate2}" />
        </MenuItem>
    </Menu>
</Grid>

关于c# - 如何在 WPF 中更改 MouseOver 上的 MenuItem 的背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24698755/

相关文章:

c# - 从 MainThread 修改控件(需要专业人士的一些理论确认)

c# - 命令行 - bool 参数不起作用

wpf - 为什么在 DataTemplate 中使用 UserControl 比直接 xaml 慢?

html - Bootstrap 下拉菜单隐藏导航链接

c# - 在 .NET Core 项目中添加引用对话框缺少程序集部分

c# - 如何在 c# 中使用静态全局定义的变量?

WPF 用户控件样式

.net - 关于在 WPF 中调试焦点问题的任何提示?

基于 Javascript 的媒体查询

javascript - 使用 Jquery 弹出滑动菜单