2009-02-05 8 views
10

Qualcuno sa come cambiare il pennello per lo sfondo di un menu? Sembra semplice, ma non vedo alcun modo ovvio per farlo. Si penserebbe che la proprietà Background lo cambierebbe, ma non lo fa.WPF C# - Cambia il pennello sullo sfondo di un menu

Ecco ciò che il mio menù si presenta come (notare lo sfondo bianco predefinito):

esempio di codice:

<Window x:Class="WpfApplication1.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Window1" Height="300" Width="300"> 

<Window.Resources> 
    <SolidColorBrush x:Key="menuItemBrush" 
        Color="#FF505050" /> 
</Window.Resources> 

<Grid x:Name="mainGrid" 
     Background="#FF252525"> 

    <Menu x:Name="mainMenu" 
      Background="{DynamicResource menuItemBrush}" 
      Grid.ColumnSpan="2" 
      VerticalAlignment="Top"> 

     <MenuItem x:Name="fileMenu" 
        Background="{DynamicResource menuItemBrush}" 
        Foreground="White" 
        Header="File"> 

      <MenuItem x:Name="fileOpenMenuItem" 
         Background="{DynamicResource menuItemBrush}" 
         Foreground="White" 
         Header="Open..." /> 

      <MenuItem x:Name="fileSaveMenuItem" 
         Background="{DynamicResource menuItemBrush}" 
         Foreground="White" 
         Header="Save" /> 

      <MenuItem x:Name="fileSaveAsMenuItem" 
         Background="{DynamicResource menuItemBrush}" 
         Foreground="White" 
         Header="Save As..." /> 

      <Separator Style="{DynamicResource menuItemSeperator}" /> 

      <MenuItem x:Name="fileExitMenuItem" 
         Background="{DynamicResource menuItemBrush}" 
         Foreground="White" 
         Header="Exit" /> 
     </MenuItem> 
    </Menu> 
</Grid> 

+1

Questo articolo sembra utile. Mostra come personalizzare i modelli di controllo degli oggetti (a differenza degli stili nella risposta di Nate): http://blogs.microsoft.co.il/blogs/pavely/archive/2010/10/01/wpf-menu-customization.aspx –

+2

Perché non hai caricato l'immagine sullo stackoverflow? Non è disponibile ora. – Tara

risposta

11

Suggerirei di utilizzare uno strumento chiamato kaxaml per scrivere stili. Include diversi frammenti di codice, un selettore di colori e un buon modo per vedere istantaneamente quali cambiamenti nel codice xaml. Ecco uno stile di menu completo per ciò che stai cercando di fare. Basta cambiare i colori del pennello in alto per soddisfare le tue esigenze.

<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> 
+1

Esiste una licenza di questo tipo e gli stili forniti con kaxaml? – NoOne

+1

@ NoOne, ogni frammento di codice pubblicato su SE utilizza implicitamente la licenza MIT. Kaxaml utilizza anche il MIT. –

0

Non si può farlo senza l'override del modello per il elemento del menu. Nel profondo del template c'è un controllo chiamato "Part_Popup". Devi cambiare il suo colore di sfondo.

+0

Come potrei fare per accedere a questa proprietà? Sarebbe bello se potessi semplicemente scavalcare quella proprietà. Ho provato a farlo attraverso il codice C# usando qualcosa come "this.FindResource (" Part_Popup) ", ma non riesce a trovare la risorsa – user62998

+0

Try myMenu.Template.FindName (" Part_Popup ", this); – Micah

+0

Ricevo un'invaliddOperationException: Questa operazione è valida solo per gli elementi a cui è applicato questo modello. Ho provato a sostituire "questo" con il menu e non funziona neanche – user62998