如何通过ControlTemplate在WPF MenuItem中插入图标
解决方法
要实现根菜单项仅显示图标,你需要在ControlTemplate中添加图标路径控件,并调整相关布局与触发器设置,具体操作如下:
- 在模板内包含ContentPresenter的Grid的第0列,添加Path控件填入你的图标路径,同时设置合适的尺寸、填充色等样式,确保图标正常显示。
- 移除原模板中
IsKeyboardFocusWithin触发器里的<Setter Property="Header" Value="Test" />代码,这行代码会强制设置文字,导致图标无法单独显示。 - 使用该模板的根菜单项,将
Header设为空字符串,避免显示文字内容。
修改后的完整ControlTemplate代码
<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> <!-- 新增的图标Path控件 --> <Path x:Name="MenuIcon" Data="M6 36v-3h36v3Zm0-10.5v-3h36v3ZM6 15v-3h36v3Z" Fill="#FFFFFF" <!-- 可根据你的主题调整颜色 --> Width="20" Height="20" Margin="4" /> <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" HorizontalOffset="-2"> <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="BorderBrush" Value="#2C2C2C"></Setter> <Setter Property="BorderThickness" Value="1"></Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate>
根菜单项使用示例
<MenuItem Template="{StaticResource MenuItemControlTemplate1}" Header=""> <!-- 子菜单内容 --> <MenuItem Header="子菜单项1"/> <MenuItem Header="子菜单项2"/> </MenuItem>
内容的提问来源于stack exchange,提问作者Aim
相关产品推荐
相关产品推荐

