How to set foreground and background colors on a WPF Menu control?
What am I missing?
Controls are more or less customizable, and there are two levels of customizing a control:
- Setting properties like
Foreground
,Background
, etc, in the XAML where you place the control. - Setting the
Template
in yourStyle
for the control, and creating your ownControlTemplate
.
The second is more involved, but it offers much more flexibility in making the control look how you want. If this case, it sounds like that's what you'll need. Check out the default ControlTemplate for Menu and MenuItem. You can copy/paste them and modify as needed.
<Window.Resources>
<Style TargetType="{x:Type Menu}">
<Setter Property="Template">
<ControlTemplate TargetType="{x:Type Menu}">
<!-- your modified template here -->
</ControlTemplate>
</Setter>
</Style>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Template">
<ControlTemplate TargetType="{x:Type MenuItem}">
<!-- your modified template here -->
</ControlTemplate>
</Setter>
</Style>
</Window.Resources>
You will want to learn more about templates and styles in WPF (XAML really). In XAML, how a control looks and how a control operates are two completely different things. In your example, you may have a Foreground and Background property, but the style\template of the control my not utilize these properties for the display of the control.
Read http://wpftutorial.net/Templates.html and http://wpftutorial.net/TemplatesStyles.html, they will give you a good and quick overview. For a more in depth look, read this: http://msdn.microsoft.com/en-us/library/ee230084.aspx
If you are using Visual Studio 2012 to edit your WPF UI, you can easily create a copy of the style\template the menu control is using, and then edit it. If you are using Visual Studio 2010, you should download and install (it may or may not be free) Expression Blend to edit your XAML UI.
Tip: If you are using Visual Studio 2012, make sure your Document Outline window pane is visible all the time. This is very handy for editing a XAML UI. Mine defaulted to being collapsed on the left side of the program. This pane is visible in Expression Blend by default.
Find the MenuItem control in the Document Outline. Right-click on it and select Edit Template->Edit a Copy...
This will create a copy of the existing look-and-feel of the menu item for you to edit. When you do this, you will be in editing mode of that template, to "pop out" of that mode, click on the little icon on the top left of the Document Outline window.
When editing the template, you can see the layout and design of the template. When a menu item is being as the drop-down part, it's really displayed like a Popup menu (right click menu). Looking through that template, what pops out at me right away is this color resource named SubMenuBackgroundBrush:
<SolidColorBrush x:Key="SubMenuBackgroundBrush" Color="#FFF5F5F5"/>
If you do a search for SubMenuBackgroundBrush you can see that it is used on a part named PART_Popup:
<Popup x:Name="PART_Popup" AllowsTransparency="true" Focusable="false" HorizontalOffset="1" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Placement="Bottom" VerticalOffset="-1">
<Themes:SystemDropShadowChrome x:Name="Shdw" Color="Transparent">
<Border x:Name="SubMenuBorder" BorderBrush="#FF959595" BorderThickness="1" Background="{StaticResource SubMenuBackgroundBrush}">
<ScrollViewer x:Name="SubMenuScrollViewer" Margin="1,0" 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="{StaticResource SubMenuBackgroundBrush}" Height="{Binding ActualHeight, ElementName=SubMenuBorder}" Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/>
</Canvas>
<Rectangle Fill="#F1F1F1" HorizontalAlignment="Left" Margin="1,2" RadiusY="2" RadiusX="2" Width="28"/>
<Rectangle Fill="#E2E3E3" HorizontalAlignment="Left" Margin="29,2,0,2" Width="1"/>
<Rectangle Fill="White" HorizontalAlignment="Left" Margin="30,2,0,2" Width="1"/>
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="true" Margin="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle"/>
</Grid>
</ScrollViewer>
</Border>
</Themes:SystemDropShadowChrome>
</Popup>
This is the popup that you see when you right-click on something that shows a menu, or a dropdown menu. Change the references from: {StaticResource SubMenuBackgroundBrush}
to {TemplateBinding Foreground}
.
When you run the program, you'll see that the main background of the popup has changed, but the area where the icon is displayed has not. These are all the <Rectangle Fill="
items in the popup control too. Change those also. The last reference to Rectangle looks like its the line splitting the icon and the text, you may not what to change that.
Enjoy the wonderful world of templates. It looks confusing and like a lot of work. It is. But when you get the hang of it, it's a very cool system. It's hard to go back to any other UI system after you get the hang of it.