tags:

views:

279

answers:

2

How can I modify my Menu so that it shows the color all the way through and not like this:

alt text

Here is my code:

<DockPanel>
    <Menu DockPanel.Dock="Right"
          Height="30"              
          VerticalAlignment="Top"
          Background="#2E404B"
          BorderThickness="2.6" 
          Foreground="#FFAA00">
        <Menu.BitmapEffect>
            <DropShadowBitmapEffect Direction="270" ShadowDepth="3" Color="#2B3841"/>
        </Menu.BitmapEffect>

        <MenuItem Header="File" >
            <MenuItem Header="New Build" Background="#2E404B"></MenuItem>
            <Separator />
            <MenuItem Header="Exit" Background="#2E404B"></MenuItem>
        </MenuItem>

        <MenuItem Header="Edit" >
            <MenuItem Header="Language" Background="#2E404B"></MenuItem>
            <MenuItem Header="Display Mode" Background="#2E404B"></MenuItem>
            <Separator />
            <MenuItem Header="Settings" Background="#2E404B"></MenuItem>
        </MenuItem>

        <MenuItem Header="View" >

        </MenuItem>
        <MenuItem Header="About" >

        </MenuItem>
    </Menu>
</DockPanel>

Also, I realize I'm setting the color in all instances of the MenuItem, if someone could show me a more efficient way of doing that, that would be awesome as well. :D

A: 

To set the background on all MenuItem instances, define a style for MenuItem:

<Style x:Key="{x:Type MenuItem}">
  <Setter Property="Background" Value="#2E404B" />
</Style>

You should be able to do the same for the Separator class to polish off the remaining bits, though due to contrast issues you might want to style the entire Template rather than just the Background.

Alternatively, you might need/want to hijack MenuItem.SeparatorStyleKey, MenuItem.TopLevelItemTemplateKey, etc.

itowlson
Unfortunately this doesn't work because the Menu style overrides the default Separator style with a custom one found in its <Style.Resources>.
Ray Burns
Did you try hijacking the SeparatorStyleKey? That is, in your own Menu.Resources, declare your own style with the key {x:Static MenuItem.SeparatorStyleKey}. Yours should then be found first when WPF searches for the separator style, and should trump the built-in style. (Haven't tested this, sorry.) Or of course you could always explicitly override the style: <Separator Style="{StaticResource MyStyle}" /> -- not as convenient but if all else fails...
itowlson
Hijacking the SeparatorStyleKey is exactly how the theme's Menu style adds the background color that Pappucino1 is trying to get rid of. When he attempts to hijack it himself, the Menu style's hijack overrides his because it is closer (inside the Menu style's private ResourceDictionary). So the Menu style's hijack trumps his and his hijacking fails.
Ray Burns
Explictly setting the Style on each MenuItem and Separator would do the job. As you say, it is not as convenient.
Ray Burns
+4  A: 

The difficulty is that the colors you need are buried deep within the Menu theme styles. These theme styles are some of the most complex among those shipped with WPF. They consist of 10-20 styles and templates.

In general I recommend creating styles similar to the one in itowlson's answer because it allows you to adapt gracefully to the current Windows theme, replacing just the properties and templates that you want different and leaving everything else the same.

In your case, overriding the theme styles piecemeal by adding indivdual tags is likely to be an exercise in futility. Fortunately you don't need to do so.

Clearly you are actually trying to create your own custom theme from a user experience point of view, so why not actually create your own theme in code? You can do this easily by copying the theme from Aero or Luna (as you prefer) and changing whatever you want to get exactly the look you want.

This is very simple to do with Expression Blend. Just:

  1. Create an empty window and add a Menu to it.
  2. Right-click the Menu, and select Edit Control Parts (Template) > Edit a Copy....
  3. In the dialog box, select Apply to All and click New beside Resource dictionary
  4. Enter the new ResourceDictionary file name, such as "MyMenuTheme.xaml"
  5. In your App.xaml, use the MergedDictionaries to include MyMenuTheme.xaml into your application resources

Now you can make any changes you want to MyMenuTheme.xaml to affect the appearance of all menus in the application. This file will be several hundred lines long but it is generally easy to find the correct settings to change. In your case it would be the various defaults for Background settings.

Note that if you don't have Expression Blend, you can also get the theme styles to start with using reflector and BAMLViewer, but that is much more work since you have to manually select the styles and other resources you need.

Ray Burns
Just a note to anyone else trying this: If you can't select "Apply to All", you have to make sure you haven't set any styles for menus already.
Deniz Dogan