如何在 WPF 的自定义 MenuItem 控件中设置鼠标悬停触发器?
How to set the mouse over trigger in custom MenuItem Control of WPF?
我有一个 MenuItem 样式:
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource {x:Type MenuItem}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate 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 Width="*"/>
<ColumnDefinition Width="4"/>
<ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="menuHeaderContainer" Grid.Column="0"
ContentSource="Header" HorizontalAlignment="Left"
Margin="{TemplateBinding Padding}" RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="Center"/>
<TextBlock x:Name="menuGestureText" Grid.Column="2"
Margin="{TemplateBinding Padding}" Opacity="0.7" Text="{TemplateBinding InputGestureText}"
VerticalAlignment="Center"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="templateRoot" Value="Black"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="IsEnabled" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="Red"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="Black"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
我的控件是:
<Grid>
<Menu VerticalAlignment="Center" HorizontalAlignment="Center">
<MenuItem Header="Header">
<MenuItem Header="Second Level"/>
</MenuItem>
</Menu>
我愿意设置鼠标悬停在菜单项上时的新样式,背景为黑色。我的风格有效,但只有二级菜单项。
当鼠标悬停在一级菜单项上时,它仍然是默认样式:
当鼠标悬停在二级菜单项上时,我的样式有效(鼠标悬停在上面时会变黑):
为什么我的样式在第一级 MenuItem 上不起作用?
顶级菜单项和子菜单项的控件模板不同。顶级 MenuItem 还需要定义子菜单项将如何弹出。
您可以为每种类型的菜单项编写多个ControlTemplate。然后使用以下样式设置菜单项样式:
<Style x:Key="{x:Type MenuItem}" TargetType="MenuItem">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Style.Triggers>
<Trigger Property="Role" Value="TopLevelHeader">
<Setter Property="Template" Value="{StaticResource {x:Static MenuItem.TopLevelHeaderTemplateKey}}"/>
<Setter Property="Grid.IsSharedSizeScope" Value="true"/>
</Trigger>
<Trigger Property="Role" Value="TopLevelItem">
<Setter Property="Template"
Value="{StaticResource {x:Static MenuItem.TopLevelItemTemplateKey}}"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuHeader">
<Setter Property="Template"
Value="{StaticResource {x:Static MenuItem.SubmenuHeaderTemplateKey}}"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuItem">
<Setter Property="Template"
Value="{StaticResource {x:Static MenuItem.SubmenuItemTemplateKey}}"/>
</Trigger>
</Style.Triggers>
</Style>
有关详细信息,请参阅此 post
我有一个 MenuItem 样式:
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource {x:Type MenuItem}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate 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 Width="*"/>
<ColumnDefinition Width="4"/>
<ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="menuHeaderContainer" Grid.Column="0"
ContentSource="Header" HorizontalAlignment="Left"
Margin="{TemplateBinding Padding}" RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="Center"/>
<TextBlock x:Name="menuGestureText" Grid.Column="2"
Margin="{TemplateBinding Padding}" Opacity="0.7" Text="{TemplateBinding InputGestureText}"
VerticalAlignment="Center"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="templateRoot" Value="Black"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsHighlighted" Value="True"/>
<Condition Property="IsEnabled" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="Red"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="Black"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
我的控件是:
<Grid>
<Menu VerticalAlignment="Center" HorizontalAlignment="Center">
<MenuItem Header="Header">
<MenuItem Header="Second Level"/>
</MenuItem>
</Menu>
我愿意设置鼠标悬停在菜单项上时的新样式,背景为黑色。我的风格有效,但只有二级菜单项。
当鼠标悬停在一级菜单项上时,它仍然是默认样式:
当鼠标悬停在二级菜单项上时,我的样式有效(鼠标悬停在上面时会变黑):
为什么我的样式在第一级 MenuItem 上不起作用?
顶级菜单项和子菜单项的控件模板不同。顶级 MenuItem 还需要定义子菜单项将如何弹出。
您可以为每种类型的菜单项编写多个ControlTemplate。然后使用以下样式设置菜单项样式:
<Style x:Key="{x:Type MenuItem}" TargetType="MenuItem">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Style.Triggers>
<Trigger Property="Role" Value="TopLevelHeader">
<Setter Property="Template" Value="{StaticResource {x:Static MenuItem.TopLevelHeaderTemplateKey}}"/>
<Setter Property="Grid.IsSharedSizeScope" Value="true"/>
</Trigger>
<Trigger Property="Role" Value="TopLevelItem">
<Setter Property="Template"
Value="{StaticResource {x:Static MenuItem.TopLevelItemTemplateKey}}"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuHeader">
<Setter Property="Template"
Value="{StaticResource {x:Static MenuItem.SubmenuHeaderTemplateKey}}"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuItem">
<Setter Property="Template"
Value="{StaticResource {x:Static MenuItem.SubmenuItemTemplateKey}}"/>
</Trigger>
</Style.Triggers>
</Style>
有关详细信息,请参阅此 post