如何解决WPF菜单项间白色空白的去除与颜色修改问题?
WPF菜单项间白色空白区域消除方案
我正在尝试修改WPF菜单项之间空白区域的颜色,已经配置了Menu、MenuItem及子MenuItem的样式,相关XAML代码如下:
<Style TargetType="Menu" x:Key="MenuTheme"> <Setter Property="Background"> <Setter.Value> <LinearGradientBrush> <GradientStop Color="Black" Offset="0"/> <GradientStop Color="LightSlateGray" Offset="0.5"/> <GradientStop Color="DarkGray" Offset="1"/> </LinearGradientBrush> </Setter.Value> </Setter> </Style> <Style TargetType="MenuItem" x:Key="MenuButtonTheme"> <Setter Property="Foreground" Value="White"/> <Setter Property="VerticalAlignment" Value="Center"/> <Setter Property="HorizontalAlignment" Value="Center"/> <Setter Property="Header" Value="{Binding Name}"/> <Setter Property="StaysOpenOnClick" Value="True"/> </Style> <Style TargetType="MenuItem" x:Key="SubMenuItemTheme"> <Setter Property="StaysOpenOnClick" Value="True"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type MenuItem}"> <Popup IsOpen="{TemplateBinding IsSubmenuOpen}" > <Border x:Name="Bd" Padding="0" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" > <ContentPresenter x:Name="ContentPresenter" Content="{TemplateBinding Header}" Margin="{TemplateBinding Padding}"/> </Border> </Popup> </ControlTemplate> </Setter.Value> </Setter> <Setter Property="Height" Value="30"/> <Setter Property="Margin" Value="0,-2,0,0"/> <Setter Property="BorderThickness" Value="0"/> <Setter Property="Header" Value="{Binding Name}"/> <Style.Triggers> <EventTrigger RoutedEvent="MouseEnter"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <ColorAnimation FillBehavior="Stop" Duration="0:0:3" To="Green" Storyboard.TargetProperty="(MenuItem.Background).(SolidColorBrush.Color)"/> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> </Style.Triggers> </Style>
当前菜单项间仍存在白色空白区域,若移除子MenuItem模板中的Popup控件,子菜单显示异常且仍无法消除白色空白。
补充Menu的XAML代码:
<Menu Grid.ColumnSpan="2" x:Name="menu" ItemsSource="{Binding menus}"> <Menu.Resources> <Style TargetType="MenuItem" BasedOn="{StaticResource MenuButtonTheme}"> <Setter Property="Height" Value="{Binding ElementName=menu, Path=ActualHeight}"/> </Style> <Style TargetType="Menu" BasedOn="{StaticResource MenuTheme}"/> <HierarchicalDataTemplate DataType="{x:Type self:MenuModel}" ItemsSource="{Binding MenuModels}"> <HierarchicalDataTemplate.ItemContainerStyle> <Style TargetType="MenuItem" BasedOn="{StaticResource SubMenuItemTheme}"/> </HierarchicalDataTemplate.ItemContainerStyle> </HierarchicalDataTemplate> </Menu.Resources> </Menu>
解决方法
问题核心是你自定义的SubMenuItemTheme模板完全替换了MenuItem的默认结构,导致子菜单容器样式丢失,且Popup本身可能继承默认白色背景,进而出现空白。以下是修正方案:
- 修正
SubMenuItemTheme的ControlTemplate,保留MenuItem核心结构:
<Style TargetType="MenuItem" x:Key="SubMenuItemTheme"> <Setter Property="StaysOpenOnClick" Value="True"/> <Setter Property="Height" Value="30"/> <Setter Property="Margin" Value="0"/> <Setter Property="Padding" Value="0"/> <Setter Property="BorderThickness" Value="0"/> <Setter Property="Header" Value="{Binding Name}"/> <Setter Property="Background" Value="Transparent"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type MenuItem}"> <Grid x:Name="templateRoot" SnapsToDevicePixels="True"> <!-- 菜单项内容区域 --> <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"> <Grid x:Name="innerGrid" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"> <ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" Margin="4,0,6,0" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/> <ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="1" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> <!-- 子菜单Popup,使用系统命名PART_Popup保证功能正常 --> <Popup x:Name="PART_Popup" AllowsTransparency="True" Focusable="False" HorizontalOffset="-2" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Placement="Right" VerticalOffset="-3"> <Border x:Name="subMenuBorder" BorderBrush="#FF999999" BorderThickness="1" Background="{TemplateBinding Background}" Padding="0"> <ScrollViewer x:Name="subMenuScrollViewer" Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}"> <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle"/> </ScrollViewer> </Border> </Popup> </Grid> </Border> </Grid> <ControlTemplate.Triggers> <EventTrigger RoutedEvent="MouseEnter"> <BeginStoryboard> <Storyboard> <ColorAnimation FillBehavior="Stop" Duration="0:0:3" To="Green" Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" Storyboard.TargetName="border"/> </Storyboard> </BeginStoryboard> </EventTrigger> <Trigger Property="IsEnabled" Value="False"> <Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="#FF707070"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
确保背景传递:
- 设置
Background为Transparent,让子菜单继承父Menu的渐变背景,避免白色空白。 - 子菜单Popup的
subMenuBorder绑定MenuItem的Background,保证背景统一。
- 设置
调整间距:
- 用
Padding控制内部间距,去掉负Margin避免布局异常。 - 若仍有空白,可将
subMenuBorder的Padding设为0,消除容器默认内边距。
- 用
修改后子菜单结构恢复正常,空白区域将使用你设置的背景颜色,不会再出现白色间隙。
内容的提问来源于stack exchange,提问作者blockchainlover
相关产品推荐
相关产品推荐

