WPF C# - Change the brush of a menu's background

后端 未结 2 1806
失恋的感觉
失恋的感觉 2020-12-17 18:31

Does anyone know how to change the brush for a menu\'s background? This sounds simple, but I don\'t see any obvious way to do this. You\'d think that the Background property

相关标签:
2条回答
  • 2020-12-17 18:55

    I'd suggest using a tool called kaxaml for writing styles. It includes several code snippets, a color picker and a nice way to instantly see what changes in the xaml code does. Here is a full menu style for what you are trying to do. Just change the brush colors at the top to suit to your needs.

    <Page
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
      <Page.Resources>
    
      <!--**************************
        * STYLE: MenuItem
        ************************** -->
      <SolidColorBrush x:Key="HighlightedBackgroundBrush" Color="#FF797878" />
      <SolidColorBrush x:Key="MenuBackgroundBrush" Color="#FF505050" />
      <SolidColorBrush x:Key="NormalBorderBrush" Color="#FFFFFFFF" />
      <SolidColorBrush x:Key="SolidMenuFontBrush" Color="#FFFFFFFF" />
      <SolidColorBrush x:Key="HighlightedText" Color="#FFFFFFFF" />
      <Style x:Key="{x:Type Menu}" TargetType="{x:Type Menu}">
        <Setter Property="OverridesDefaultStyle" Value="True"/>
        <Setter Property="SnapsToDevicePixels" Value="True"/>
        <Setter Property="Height" Value="25"/>
        <Setter Property="Foreground" Value="{StaticResource SolidMenuFontBrush}"/>
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="{x:Type Menu}">
              <Border
                Background="{StaticResource MenuBackgroundBrush}"
                BorderBrush="{StaticResource MenuBackgroundBrush}"
                BorderThickness="1">
                <StackPanel ClipToBounds="True" Orientation="Horizontal" IsItemsHost="True"/>
              </Border>
            </ControlTemplate>
          </Setter.Value>
        </Setter>
      </Style>
      <Style x:Key="{x:Type MenuItem}" TargetType="{x:Type MenuItem}">
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="{x:Type MenuItem}">
              <Border x:Name="Border"
                      Background="{TemplateBinding Background}"
                      BorderBrush="{TemplateBinding BorderBrush}"
                      BorderThickness="1">
                <Grid>
                  <Grid.ColumnDefinitions>
                    <ColumnDefinition x:Name="Col0" MinWidth="17" Width="Auto" SharedSizeGroup="MenuItemIconColumnGroup"/>
                    <ColumnDefinition Width="Auto" SharedSizeGroup="MenuTextColumnGroup"/>
                    <ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemIGTColumnGroup"/>
                    <ColumnDefinition x:Name="Col3" Width="14"/>
                  </Grid.ColumnDefinitions>
    
                  <!-- ContentPresenter to show an Icon if needed -->
                  <ContentPresenter Grid.Column="0" Margin="4,0,6,0" x:Name="Icon" VerticalAlignment="Center" ContentSource="Icon"/>
    
                  <!-- Glyph is a checkmark if needed for a checkable menu -->
                  <Grid Grid.Column="0" Visibility="Hidden" Margin="4,0,6,0" x:Name="GlyphPanel" VerticalAlignment="Center">
                    <Path x:Name="GlyphPanelpath" VerticalAlignment="Center" Fill="{TemplateBinding Foreground}" Data="M0,2 L0,4.8 L2.5,7.4 L7.1,2.8 L7.1,0 L2.5,4.6 z" FlowDirection="LeftToRight"/>
                  </Grid>
    
                  <!-- Content for the menu text etc -->
                  <ContentPresenter Grid.Column="1"
                                    Margin="{TemplateBinding Padding}"
                                    x:Name="HeaderHost"
                                    RecognizesAccessKey="True"
                                    ContentSource="Header"/>
    
                  <!-- Content for the menu IGT -->
                  <ContentPresenter Grid.Column="2"
                                    Margin="8,1,8,1"
                                    x:Name="IGTHost"
                                    ContentSource="InputGestureText"
                                    VerticalAlignment="Center"/>
    
                  <!-- Arrow drawn path which points to the next level of the menu -->
                  <Grid Grid.Column="3" Margin="4,0,6,0" x:Name="ArrowPanel" VerticalAlignment="Center">
                    <Path x:Name="ArrowPanelPath" HorizontalAlignment="Right" VerticalAlignment="Center" Fill="{TemplateBinding Foreground}" Data="M0,0 L0,8 L4,4 z"/>
                  </Grid>
    
                  <!-- The Popup is the body of the menu which expands down or across depending on the level of the item -->
                  <Popup IsOpen="{Binding Path=IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" Placement="Right" x:Name="SubMenuPopup" Focusable="false" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}">
                    <Border x:Name="SubMenuBorder" BorderBrush="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type Menu}}}" BorderThickness="1" Padding="2,2,2,2">
                      <Grid x:Name="SubMenu" Grid.IsSharedSizeScope="True">
                        <!-- StackPanel holds children of the menu. This is set by IsItemsHost=True -->
                        <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle"/>
                      </Grid>
                    </Border>
                  </Popup>
                </Grid>
              </Border>
    
              <!-- These triggers re-configure the four arrangements of MenuItem to show different levels of menu via Role -->
              <ControlTemplate.Triggers>
                <!-- Role = TopLevelHeader : this is the root menu item in a menu; the Popup expands down -->
                <Trigger Property="Role" Value="TopLevelHeader">
                  <Setter Property="Padding" Value="6,1,6,1"/>
                  <Setter Property="Placement" Value="Bottom" TargetName="SubMenuPopup"/>
                  <Setter Property="MinWidth" Value="0" TargetName="Col0"/>
                  <Setter Property="Width" Value="Auto" TargetName="Col3"/>
                  <Setter Property="Visibility" Value="Collapsed" TargetName="Icon"/>
                  <Setter Property="Visibility" Value="Collapsed" TargetName="GlyphPanel"/>
                  <Setter Property="Visibility" Value="Collapsed" TargetName="IGTHost"/>
                  <Setter Property="Visibility" Value="Collapsed" TargetName="ArrowPanel"/>
                </Trigger>
    
                <!-- Role = TopLevelItem :  this is a child menu item from the top level without any child items-->
                <Trigger Property="Role" Value="TopLevelItem">
                  <Setter Property="Padding" Value="6,1,6,1"/>
                  <Setter Property="Visibility" Value="Collapsed" TargetName="ArrowPanel"/>
                </Trigger>
    
                <!-- Role = SubMenuHeader : this is a child menu item which does not have children -->
                <Trigger Property="Role" Value="SubmenuHeader">
                  <Setter Property="DockPanel.Dock" Value="Top"/>
                  <Setter Property="Padding" Value="0,2,0,2"/>
                </Trigger>
    
                <!-- Role = SubMenuItem : this is a child menu item which has children-->
                <Trigger Property="Role" Value="SubmenuItem">
                  <Setter Property="DockPanel.Dock" Value="Top"/>
                  <Setter Property="Padding" Value="0,2,0,2"/>
                  <Setter Property="Visibility" Value="Collapsed" TargetName="ArrowPanel"/>
                </Trigger>
                <Trigger Property="IsSuspendingPopupAnimation" Value="true">
                  <Setter Property="PopupAnimation" Value="None" TargetName="SubMenuPopup"/>
                </Trigger>
    
                <!-- If no Icon is present the we collapse the Icon Content -->
                <Trigger Property="Icon" Value="{x:Null}">
                  <Setter Property="Visibility" Value="Collapsed" TargetName="Icon"/>
                </Trigger>
    
                <!-- The GlyphPanel contains the CheckMark -->
                <Trigger Property="IsChecked" Value="true">
                  <Setter Property="Visibility" Value="Visible" TargetName="GlyphPanel"/>
                  <Setter Property="Visibility" Value="Collapsed" TargetName="Icon"/>
                </Trigger>
    
                <!-- Using the system colors for the Menu Highlight and IsEnabled-->
                <Trigger Property="IsHighlighted" Value="true">
                  <Setter Property="Background" Value="{StaticResource HighlightedBackgroundBrush}" TargetName="Border"/>
                  <Setter Property="Foreground" Value="{StaticResource HighlightedText}"/>
                  <Setter Property="BorderBrush" Value="{StaticResource NormalBorderBrush}" TargetName="Border"/>
                </Trigger>
                <Trigger Property="IsHighlighted" Value="false">
                  <Setter Property="Background" Value="{StaticResource MenuBackgroundBrush}" TargetName="Border"/>
                  <Setter Property="Foreground" Value="{StaticResource SolidMenuFontBrush}"/>
                  <Setter Property="BorderBrush" Value="{StaticResource MenuBackgroundBrush}" TargetName="Border"/>
                </Trigger>
                <Trigger Property="IsEnabled" Value="false">
                  <Setter Property="Foreground" Value="LightGray"/>
                </Trigger>
              </ControlTemplate.Triggers>
            </ControlTemplate>
          </Setter.Value>
        </Setter>
      </Style>
      </Page.Resources>
    <Grid x:Name="mainGrid"
          Background="#FF252525">
    
        <Menu x:Name="mainMenu"
              Grid.ColumnSpan="2"
              VerticalAlignment="Top">
    
            <MenuItem x:Name="fileMenu"
                      Header="File">
    
                <MenuItem x:Name="fileOpenMenuItem"
                          Header="Open..." />
    
                <MenuItem x:Name="fileSaveMenuItem"
                          Header="Save" />
    
                <MenuItem x:Name="fileSaveAsMenuItem"
                          Background="{DynamicResource menuItemBrush}"
                          Header="Save As..." />
            </MenuItem>
        </Menu>
      </Grid>
    </Page>
    
    0 讨论(0)
  • 2020-12-17 19:11

    You can't do it without overriding the template for the menu item. Deep inside the template is a control called "Part_Popup". You need to change it's background color.

    0 讨论(0)
提交回复
热议问题