我正在尝试在WPF项目中创建一个基本的菜单系统。我已通过App.xaml
应用了附加样式。当我单击顶级菜单项时,它的sub-MenuItems不会显示。
我怀疑应该对ContentPresenter进行重构,但是找不到关于正确配置的任何内容。
我应该重构什么才能使这种简单的样式与sub-MenuItems一起使用?
App.xaml
中的附加样式:
<Style TargetType="{x:Type Menu}">
<Setter Property="Foreground" Value="#ffffff"/>
<Setter Property="Background" Value="#da4148"/>
</Style>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Foreground" Value="#ffffff"/>
<Setter Property="Background" Value="#da4148"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Border x:Name="Border" Background="{TemplateBinding Background}"
SnapsToDevicePixels="True" Uid="Border_38" Margin="0,10,0,0" Padding="3">
<ContentPresenter x:Name="ContentPresenter" Content="{TemplateBinding Header}"
Grid.Column="1" ContentSource="Header" Margin="{TemplateBinding Padding}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="Border" Value="#ffffff"/>
<Setter Property="TextBlock.Foreground" TargetName="Border" Value="#da4148"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
菜单本身:
<DockPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3">
<Menu DockPanel.Dock="Top" Margin="0" Grid.ColumnSpan="2">
<MenuItem Command="{Binding OpenHomePageCommand}">
<MenuItem.Header>
<StackPanel>
<Image Width="20" Height="20" Source="pack://application:,,,/Resources/Images/home.png" />
<ContentPresenter Content="Home" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem Header="{DynamicResource File}" Height="40">
<MenuItem Header="{DynamicResource SaveFile}" Command="{Binding SaveFileCommand}" CommandParameter="{Binding FileDisplayerViewModel.DisplayedFile}" Height="30"/>
<MenuItem Header="{DynamicResource Exit}" Command="{Binding CloseApplicationCommand}" Height="30"/>
</MenuItem>
<MenuItem Header="{DynamicResource Settings}" Height="40">
<MenuItem Header="{DynamicResource Watermark}" Command="{Binding ShowWatermarkWindowCommand}" Height="30"/>
<MenuItem Header="{DynamicResource Language}" Height="30">
<MenuItem Header="{DynamicResource English}" Command="{Binding SetEnglishLanguageCommand}" Height="30"/>
<MenuItem Header="{DynamicResource Hungarian}" Command="{Binding SetHungarianLanguageCommand}" Height="30"/>
</MenuItem>
<MenuItem Header="{DynamicResource ApplicationProperties}" Command="{Binding ShowApplicationPropertiesWindowCommand}" Height="30"/>
</MenuItem>
<MenuItem Header="{DynamicResource Help}" Height="40">
<MenuItem Header="{DynamicResource Help}" Height="30" Command="{Binding OpenHelpWebsiteCommand}"/>
<MenuItem Header="{DynamicResource About}" Height="30" Command="{Binding AboutCommand}"/>
</MenuItem>
</Menu>
</DockPanel>
当我将鼠标移到MenuItem上时,悬停样式有效,但未显示sub-MenuItem:
答案 0 :(得分:0)
Menu
是一个完全由MenuItem
元素组成的树结构。它具有根节点(标题项)和子节点(子项)。如果子项也是一个节点(可以有子节点),则该节点也必须是标头。标头也是MenuItem
,但模板不同。它有一个popup
,其中包含一个显示子项的项目面板。
现在,您正在使用一个隐式Style
,它也将覆盖所有标头项目,并将其转换为可以容纳子项目并且不能扩展(没有弹出窗口)的普通子项目。因此,您基本上缺少包含子菜单项的Popup
。如果您还想覆盖标题模板,则必须添加类似以下内容:
<!-- TopLevelHeader -->
<ControlTemplate x:Key="{x:Static MenuItem.TopLevelHeaderTemplateKey}"
TargetType="{x:Type MenuItem}">
<Border x:Name="Border">
<Grid>
<ContentPresenter Margin="6,3,6,3"
ContentSource="Header"
RecognizesAccessKey="True" />
<Popup x:Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Fade">
<Border x:Name="SubmenuBorder"
SnapsToDevicePixels="True"
BorderThickness="1"
Background="{DynamicResource MenuPopupBrush}">
<Border.BorderBrush>
<SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
</Border.BorderBrush>
<ScrollViewer CanContentScroll="True"
Style="{StaticResource MenuScrollViewer}">
<StackPanel IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Cycle" />
</ScrollViewer>
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSuspendingPopupAnimation"
Value="true">
<Setter TargetName="Popup"
Property="PopupAnimation"
Value="None" />
</Trigger>
<Trigger Property="IsHighlighted"
Value="true">
<Setter TargetName="Border"
Property="BorderBrush"
Value="Transparent" />
<Setter Property="Background"
TargetName="Border">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{StaticResource ControlLightColor}" />
<GradientStop Color="{StaticResource ControlMouseOverColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger SourceName="Popup"
Property="AllowsTransparency"
Value="True">
<Setter TargetName="SubmenuBorder"
Property="CornerRadius"
Value="0,0,4,4" />
<Setter TargetName="SubmenuBorder"
Property="Padding"
Value="0,0,0,3" />
</Trigger>
<Trigger Property="IsEnabled"
Value="False">
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Color="{StaticResource DisabledForegroundColor}" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
或者,您可以使MenuItem
样式明确,并将其直接应用于子菜单项。
但是推荐的方法是使用Menu
正在使用的资源模板键。只需定义一个ControlTemplate and override the template resource key (e.g.:
TopLevelHeaderTemplateKey or
SubmenuHeaderTemplateKey`)
标题项目:
<ControlTemplate x:Key="{x:Static MenuItem.TopLevelHeaderTemplateKey}"
TargetType="{x:Type MenuItem}">
</ControlTemplate>
您可以在Microsoft Docs上找到完整的默认模板。它显示了如何覆盖所有四个模板资源键。您可以修改它们以满足您的要求。
每个资源密钥都映射到MenuItemRole
(例如TopLevelHeader
)。使用资源键描述布局,使用角色描述行为。