Click here to Skip to main content
12,297,578 members (52,181 online)
Click here to Skip to main content
Add your own
alternative version


208 bookmarked

Visual Studio 2012 Metro Styles for WPF

, 9 Dec 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
Black Metro Styles for Button, ListBox, Menu, ScrollBar, TabControl, TextBox, ComboBox, DataGrid and GroupBox



Although there are still serious discussions about whether the "Metro" design concept from Microsoft is good or not, WPF developers, who follow the trend, may now write their styles keeping the concept in mind. But despite the fact that many people think about the Tile Wall of Windows 8, when they hear the word "Metro", the concept itself actually means much more than that. The main idea is to keep things simple. No more gradients, no more colorful, blinking, glassy, flashing surfaces. One of the applications demonstrating this concept best is, no doubt, the new Visual Studio 2012. This article will present some Visual Studio like WPF styles.

"Styles like visual studio" means, that I didn´t copy the styles of course (using a decompiler or something) and so they aren´t actually equal, but I used the same colors and I structured my demo application like VS. I will discuss some of the main differences later.


First some screenshots of what we´ll end up with, to show you what I´m talking about:

Using the styles

To structure the styles a bit, I´ve put each in a different ResourceDictionary named after the control to be styled. If you don´t want to use all styles, you´ll have to embed each ResourceDictionary by yourself via MergedDictionaries. In this case it´s also necessary to reference the styles explicitly, because they all have a key. If you want to use the complete set, just add the Styles.xaml ResourceDictionary to the MergedDictionaries.

Use complete style set



styles will be automatically applied to each control

Use parts of it



where you want to use the style:

<Button Content="blastallenemies.cmd" Style="{StaticResource LinkButton}"/>

List of all styles

For future reference, here is a complete list of the styles and the corresponding keys:

Target typeStyle Key


Some words about metro

Before we´ll talk about the WPF implementation, I want to summarize the general goal we are pursuing:

  • In short, Metro means focusing on the content
  • Only sharp edges
  • No blurry lines
  • No gradients
  • Only few colors (this is not always the case, but I like it, because it again underlines the importance of the content)

As I focused on the black style, we can add the following two rules:

  • Dark background
  • White foreground

What does this mean?

Now we know what we want, so let´s see what this means in XAML:


As we only have few colors, I decided to put them all in a seperate ResourceDictionary (Resources.xaml in Selen.Wpf.Core) for easy access. We basically have:

  • Window Background (I applied that by a separate window style, wich I didn´t consider worth being mentioned before, because it does nothing more than that)
  • Foreground for everything
  • Normal, Highlighted and SelectedBackground and BorderBrush (for many controls the same)


Borders can be found in (nearly) every style. Because they all look similar, we can say something general about them:

  • BorderThickness should be equal to 1 or 0 (large borders are not proper for the metro style)
  • CornerRadius should be always 0 (no rounded edges)
  • Background and BorderBrush should be set to the mentioned colors as needed
  • SnapsToDevicePixels should be set to true. For those of you, who don´t know about this property: it basically tells WPF to turn off antialiasing and so make a hard cut between the Border and its environment. This prevents our Border from appearing blurry.

Note: There are some exceptions to these rules, because I sometimes use a Border to do other things than creating an actual border, as we´ll see later.


The best example so far is the Button Style, because it just consist of a Border. So here it is, nothing to be surprised about:

<Style x:Key="StandardButton" TargetType="Button">
    <Setter Property="Visibility" Value="Visible"/>
    <Setter Property="Foreground" Value="{StaticResource Foreground}"/>
    <Setter Property="Background" Value="{StaticResource BackgroundNormal}"/>
    <Setter Property="BorderBrush" Value="{StaticResource BorderBrushNormal}"/>
    <Setter Property="Template">
            <ControlTemplate TargetType="Button">
                <Border SnapsToDevicePixels="True"
                        BorderBrush="{TemplateBinding BorderBrush}" 
                        Background="{TemplateBinding Background}">
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="BorderBrush" Value="{StaticResource BorderBrushHighlighted}" />
                        <Setter Property="Background" Value="{StaticResource BackgroundHighlighted}" />
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="Background" Value="{StaticResource BackgroundSelected}"/>
                        <Setter Property="BorderBrush" Value="{StaticResource BorderBrushSelected}"/>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Visibility" Value="Hidden"/>


I don´t want to discuss every single line of the styles now, because many things are the same like what we already discussed or are just logical and don´t really need much explanation to be understood (for instance switching background via Trigger on MouseEnter). But I want to point some interesting things out, on the one hand to give you some ideas for your own work, on the other hand to give you a better understanding of what I did.

Link Button

First the two "out of band" styles - LinkButton and SearchTextBox. The idea of the LinkButton is pretty simple, it´s just a TextBlock that wrapps up the ContentPresenter:

<ControlTemplate TargetType="Button">

The Button forwards its Foreground to the child elements, so we can change the Foreground of our TextBlock that way in an ordinary Trigger:

    <Trigger Property="IsMouseOver" Value="true">
        <Setter Property="Foreground" Value="{StaticResource LinkButtonHighlightedForeground}" />

Search TextBox

The SearchTextBox is basically a normal TextBox with a special ControlTemplate that hosts the Text itself and an additional TextBlock, wich is responsible for displaying the "Search ..." text. Our second task is to expand the functionality of our Triggers to hide/display the "Search ..." text besides the background color switching:

<ControlTemplate TargetType="{x:Type TextBox}">
    <Grid Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
        <TextBlock Foreground="{StaticResource SearchTextForeground}" Margin="5,0,0,0" 
                   VerticalAlignment="Center" Name="search" Text="Search ..." Visibility="Hidden"/>
        <ScrollViewer x:Name="PART_ContentHost" Margin="1"/>
        <Trigger Property="TextBox.Text" Value="">
            <Setter TargetName="search" Property="Visibility" Value="Visible"/>
        <Trigger Property="TextBox.Text" Value="{x:Null}">
            <Setter TargetName="search" Property="Visibility" Value="Visible"/>
        <Trigger Property="IsMouseOver" Value="true">
            <Setter Property="Background" Value="{StaticResource TextBoxBackgroundSelected}" />
            <Setter TargetName="search" Property="Foreground" Value="{StaticResource Foreground}" />
        <Trigger Property="IsFocused" Value="true">
            <Setter Property="Background" Value="{StaticResource TextBoxBackgroundSelected}" />
            <Setter TargetName="search" Property="Visibility" Value="Hidden"/>

Tab Control

The TabControl ControlTemplate might be worth a word or two. That´s because mostly just the TabItems are styled, so you might be interested in something different. There are two main reasons for the ControlTemplate to be changed:

  • Adding the blue horizontal line between the header and the content part of the TabControl (we´re "misusing" a Border for this task)
  • Changing the background of the header to transparent (different than the TabControl´s background itself). That´s because we want to seperate our tab content from the environment by giving it another background.

As you can see, the major changes in comparision to the default template are two Borders, one for the horizontal line and one for the tab content´s background.

<ControlTemplate TargetType="{x:Type TabControl}">
    <Grid KeyboardNavigation.TabNavigation="Local">
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        <Border Background="Transparent" BorderThickness="0,0,0,3" 
                BorderBrush="{StaticResource BackgroundSelected}">
            <TabPanel Name="HeaderPanel" Panel.ZIndex="1" Margin="0,0,4,-1" 
                IsItemsHost="True" KeyboardNavigation.TabIndex="1"/>
        <Border Grid.Row="1" Background="{StaticResource Background}"/>
        <ContentPresenter Grid.Row="1" Name="PART_SelectedContentHost" 

The TabItem Style is again very straightforward.

Adding a border around an expanded MenuItem

This is something strange now, and it´s a very small thing, that perhaps nobody will ever take notice of, but I saw it in VS and delighted in it: it´s the border around an expanded MenuItem.

As you may ask yourself, what´s strange about such a thing, let´s first have a look at this picture (the border I mean is highlighted red):

The problem is obvious: We need such a custom shaped border. But as we actually have a MenuItem and a Popup among it, we are forced to create two Borders. This might give you an idea and .. yes, it´s that dirty. We´re creating a third Border, wich overlays the lower border partially, where the two first borders converge. So we´re binding the Width of the third border to the ActualWidth of the first one. Doing this while having SnapsToDevicePixels set to true, leads to some very weird effects, because WPF sometimes "snaps" the MenuItem to a different physical pixel than our third border, so we have to make an exception to this rule. Here is the ready ControlTemplate:

<ControlTemplate TargetType="{x:Type MenuItem}">
    <!--Border 1-->
    <Border x:Name="Border" Background="Transparent" BorderBrush="Transparent" 
            BorderThickness="1" SnapsToDevicePixels="False">
        <Grid x:Name="Grid">
                <ColumnDefinition x:Name="Col0" MinWidth="17" Width="Auto" 
                <ColumnDefinition Width="Auto" SharedSizeGroup="MenuTextColumnGroup"/>
                <ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemIGTColumnGroup"/>
                <ColumnDefinition x:Name="Col3" Width="14"/>
            <ContentPresenter Grid.Column="0" x:Name="Icon" VerticalAlignment="Center" 
            <ContentPresenter Grid.Column="1" Margin="{TemplateBinding Padding}" 
                              x:Name="HeaderHost" RecognizesAccessKey="True" 
                              ContentSource="Header" VerticalAlignment="Center"/>
            <ContentPresenter Grid.Column="2" Margin="8,1,8,1" x:Name="IGTHost" 
                              ContentSource="InputGestureText" VerticalAlignment="Center"/>
            <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"/>
            <Popup IsOpen="{Binding Path=IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" 
                   Placement="Right" HorizontalOffset="-1" x:Name="SubMenuPopup" Focusable="false"
                   PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}"
                <Grid Margin="0,0,5,5">
                    <!--Border 2-->
                    <Border x:Name="SubMenuBorder" 
                            BorderBrush="{StaticResource MenuSeparatorBorderBrush}"
                            BorderThickness="1" Background="{StaticResource SubmenuItemBackground}" 
                        <Grid x:Name="SubMenu" Grid.IsSharedSizeScope="True" Margin="2">
                            <StackPanel IsItemsHost="True" 
                            <DropShadowEffect ShadowDepth="2" Color="Black"/>
                    <!--Border 3-->
                    <Border Margin="1,0,0,0" x:Name="TransitionBorder" Width="0" Height="2" 
                            VerticalAlignment="Top" HorizontalAlignment="Left" 
                            Background="{StaticResource SubmenuItemBackground}" SnapsToDevicePixels="False"
                            BorderThickness="1" BorderBrush="{StaticResource SubmenuItemBackground}"/>
    <!--A whole bunch of triggers-->

As the Triggers only do the usual work (changing background, and so on) and there are quite many of them, I decided to leave them out. If you´re interested, download the source and have a look at them.


Because VS still has the (in my opinion inappropriate) standard ScrollBar Style, I decided to build an own. The idea is simple. To fit into the style set, we need a rectangular ScrollBarThumb and rectangular ScrollBarLineButtons. The implementation is then again very straightforward: A border and the corresponding triggers. If we take the ScrollBarThumb, for instance, it looks exactly like the Button Style we talked about before:

<Style x:Key="ScrollBarThumb" TargetType="{x:Type Thumb}">
    <Setter Property="SnapsToDevicePixels" Value="true"/>
    <Setter Property="IsTabStop" Value="false"/>
    <Setter Property="Focusable" Value="false"/>
    <Setter Property="Background" Value="{StaticResource BackgroundNormal}"/>
    <Setter Property="BorderBrush" Value="{StaticResource BorderBrushNormal}"/>
    <Setter Property="Template">
            <ControlTemplate TargetType="{x:Type Thumb}">
                <Border Background="{TemplateBinding Background}" 
                        BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" />
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="{StaticResource BackgroundHighlighted}"/>
                        <Setter Property="BorderBrush" Value="{StaticResource BorderBrushHighlighted}"/>
                    <Trigger Property="IsDragging" Value="True">
                        <Setter Property="Background" Value="{StaticResource BackgroundSelected}"/>
                        <Setter Property="BorderBrush" Value="{StaticResource BorderBrushSelected}"/>

The demo application

For demonstration purposes, I´ve put together a little application. Don´t expect it to do something senseful, it´s just for showing the styles and there´s absolutely no logic behind it. Even the close buttons of the TabControl don´t work, because I dind´t want to have any single line C# code in the project to keep you from having to winkle the bindings to code out the styles and so to make it as easy as possible for you to use the styles in your own applications.

MetroWindow Update

The demo now makes use of the MetroWindow from the MahApps.Metro project (You can find the dll in the lib directory). To make the MetroWindow looking like Visual Studio, we have to add the following to Resources.xaml in Selen.Wpf.Core:

<Color x:Key="AccentColor">#2D2D30</Color>
<Color x:Key="WhiteColor">#2D2D30</Color>
<Color x:Key="BlackColor">#FFFFFFFF</Color>

AccentColor defines the background of the Titlebar (where the close, minimize .. buttons are placed on) and WhiteColor is the MetroWindow background, wich is the same like the first one to get the VS look. BlackColor sets the Foreground for everything.

Note that you can´t use most of the other MahApps.Metro controls with this AccentColor, because they also depend on it. There is unfortunately no option to set just the background of the TitleBar, but as we only use the MetroWindow in this example, it´s possible to do it via the AccentColor.

Points of interest

I think many of you know this, but in my opinion it´s crucial to set FocusVisualStyle to null on any TabItem or ListBoxItem to keep them from getting these ugly dashed borders around them when being selected by keyboard, so I just wanted to mention it, never forget that!

<Setter Property="FocusVisualStyle" Value="{x:Null}"/>


Ok, as you kept up till here, I think you don´t totally dislike the Metro concept (at least if you didn´t skip the whole article), so I hope you liked my styles as well. Of course, design is a controversial subject, but having a design concept in mind brings some structure into your application and I think an application with each control styled the same way, nevertheless you might call this boring, is more user friendly than an application with another cool, flashy effect for each control.


  • 9th Dec 2012 - Closing logic for TabItems, TreeView style
  • 10th Oct 2012 - Added style for GroupBox, fixed horizontal ScrollBar issue
  • 03rd Oct 2012 - Added style for ComboBox
  • 30th Sept 2012 - Added style for DataGrid
  • 28th Aug 2012 - Demo uses MahApps.Metro MetroWindow
  • 22nd Aug 2012 - first publish


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Winfried Lötzsch
Germany Germany
I´m a student and hobby programmer (mostly C#) from Germany.
For those German guys, who might be looking for a translated version of my stuff, I´m running a blog.

You may also be interested in...

Comments and Discussions

QuestionaVisual Studio Light Theme Pin
Milker1235-Oct-15 4:12
memberMilker1235-Oct-15 4:12 
QuestionDeactivated Border & Titlebar font size Pin
FluffyMule25-Feb-15 18:02
memberFluffyMule25-Feb-15 18:02 
QuestionMenu border Pin
Member 112151227-Nov-14 21:12
memberMember 112151227-Nov-14 21:12 
QuestionComboBox behaviour Pin
Goran Mitrovic18-Oct-14 14:57
memberGoran Mitrovic18-Oct-14 14:57 
AnswerRe: ComboBox behaviour Pin
Goran Mitrovic19-Oct-14 3:06
memberGoran Mitrovic19-Oct-14 3:06 
QuestionAny chance u post the source code for the treeview? Pin
Member 1028063011-Aug-14 12:34
memberMember 1028063011-Aug-14 12:34 
QuestionHow add TablItem on Runtime Pin
jomynn16-Jul-14 17:29
memberjomynn16-Jul-14 17:29 
AnswerRe: How add TablItem on Runtime Pin
Member 883882715-Oct-14 4:36
memberMember 883882715-Oct-14 4:36 
Questionwindow resizing Pin
Brian Bonani15-Jul-14 10:44
memberBrian Bonani15-Jul-14 10:44 
AnswerRe: window resizing Pin
Member 1098659516-Oct-14 4:27
memberMember 1098659516-Oct-14 4:27 
QuestionThis is cool! Pin
Vincent Okeyo12-Jul-14 3:49
memberVincent Okeyo12-Jul-14 3:49 
QuestionMahApps.Metro Pin
ilia.broudno22-Apr-14 9:08
memberilia.broudno22-Apr-14 9:08 
AnswerRe: MahApps.Metro Pin
edaniel198412-Sep-14 3:17
memberedaniel198412-Sep-14 3:17 
Questionselected values in listview Pin
Techno Live23-Feb-14 21:55
groupTechno Live23-Feb-14 21:55 
QuestionCloseButton Pressing Color Pin
daiyoko24-Dec-13 2:04
memberdaiyoko24-Dec-13 2:04 
QuestionError TabControl Pin
Member 1047320918-Dec-13 16:04
memberMember 1047320918-Dec-13 16:04 
AnswerRe: Error TabControl Pin
Member 1047320931-Dec-13 19:26
memberMember 1047320931-Dec-13 19:26 
GeneralRe: Error TabControl Pin
Member 86414452-Mar-14 11:33
memberMember 86414452-Mar-14 11:33 
GeneralRe: Error TabControl Pin
Member 1047697319-Sep-14 11:22
memberMember 1047697319-Sep-14 11:22 
GeneralRe: Error TabControl Pin
Member 1047320919-Sep-14 11:53
memberMember 1047320919-Sep-14 11:53 
QuestionToolbar ? Pin
AGAWOOT19-Nov-13 16:47
memberAGAWOOT19-Nov-13 16:47 
AnswerRe: Toolbar ? Pin
Winfried Lötzsch20-Nov-13 1:59
memberWinfried Lötzsch20-Nov-13 1:59 
QuestionMenu style is missing some items Pin
Dirkster9925-Oct-13 8:13
memberDirkster9925-Oct-13 8:13 
QuestionWARNING: "Assembly 'Selen.Wpf.Core' is not referenced by this project" Pin
Member 1026761719-Sep-13 20:45
memberMember 1026761719-Sep-13 20:45 
AnswerRe: WARNING: "Assembly 'Selen.Wpf.Core' is not referenced by this project" Pin
geprogrammer20-Sep-13 0:07
membergeprogrammer20-Sep-13 0:07 
GeneralRe: WARNING: "Assembly 'Selen.Wpf.Core' is not referenced by this project" Pin
Member 1026761720-Sep-13 0:22
memberMember 1026761720-Sep-13 0:22 
GeneralRe: WARNING: "Assembly 'Selen.Wpf.Core' is not referenced by this project" Pin
geprogrammer29-Sep-13 21:56
membergeprogrammer29-Sep-13 21:56 
GeneralRe: WARNING: "Assembly 'Selen.Wpf.Core' is not referenced by this project" Pin
geprogrammer29-Sep-13 22:26
membergeprogrammer29-Sep-13 22:26 
QuestionTabButtons Not Firing CloseCommand Pin
Camuvingian4-Sep-13 3:53
memberCamuvingian4-Sep-13 3:53 
QuestionOpenFile SaveFile dialogs Pin
geprogrammer25-Feb-13 22:11
membergeprogrammer25-Feb-13 22:11 
AnswerRe: OpenFile SaveFile dialogs Pin
Fernando E. Braz22-Mar-13 7:12
memberFernando E. Braz22-Mar-13 7:12 
AnswerRe: OpenFile SaveFile dialogs Pin
Fernando E. Braz22-Mar-13 7:19
memberFernando E. Braz22-Mar-13 7:19 
Questioni cant figure out how to use this! Pin
Daniel Barga15-Feb-13 15:42
memberDaniel Barga15-Feb-13 15:42 
AnswerRe: i cant figure out how to use this! Pin
Fernando E. Braz22-Mar-13 7:23
memberFernando E. Braz22-Mar-13 7:23 
QuestionProject on GitHub? Pin
Pascalsz6-Jan-13 20:54
memberPascalsz6-Jan-13 20:54 
AnswerRe: Project on GitHub? Pin
Winfried Lötzsch12-Jan-13 6:36
memberWinfried Lötzsch12-Jan-13 6:36 
GeneralRe: Project on GitHub? Pin
jiju chovva12-Feb-13 17:14
memberjiju chovva12-Feb-13 17:14 
QuestionCommand Binding issue for Menus Pin
Chandramouleswaran28-Dec-12 21:18
memberChandramouleswaran28-Dec-12 21:18 
AnswerRe: Command Binding issue for Menus Pin
Winfried Lötzsch1-Jan-13 8:18
memberWinfried Lötzsch1-Jan-13 8:18 
GeneralRe: Command Binding issue for Menus Pin
Chandramouleswaran1-Jan-13 11:32
memberChandramouleswaran1-Jan-13 11:32 
GeneralRe: Command Binding issue for Menus Pin
Winfried Lötzsch2-Jan-13 3:45
memberWinfried Lötzsch2-Jan-13 3:45 
GeneralRe: Command Binding issue for Menus Pin
Chandramouleswaran17-Jan-13 3:06
memberChandramouleswaran17-Jan-13 3:06 
GeneralRe: Command Binding issue for Menus Pin
Winfried Lötzsch17-Jan-13 6:10
memberWinfried Lötzsch17-Jan-13 6:10 
GeneralRe: Command Binding issue for Menus Pin
Chandramouleswaran21-Feb-13 8:14
memberChandramouleswaran21-Feb-13 8:14 
QuestionSiverlight port? Pin
Andrew Sv11-Dec-12 12:15
memberAndrew Sv11-Dec-12 12:15 
AnswerRe: Siverlight port? Pin
Winfried Lötzsch13-Dec-12 6:23
memberWinfried Lötzsch13-Dec-12 6:23 
GeneralGreat job! Pin
akak68-Dec-12 18:26
memberakak68-Dec-12 18:26 
GeneralRe: Great job! Pin
Winfried Lötzsch9-Dec-12 0:29
memberWinfried Lötzsch9-Dec-12 0:29 
GeneralCheckboxes ? Pin
Milorad Menjic4-Dec-12 2:16
memberMilorad Menjic4-Dec-12 2:16 
GeneralRe: Checkboxes ? Pin
Winfried Lötzsch8-Dec-12 23:31
memberWinfried Lötzsch8-Dec-12 23:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160525.2 | Last Updated 9 Dec 2012
Article Copyright 2012 by Winfried Lötzsch
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid