A Windows Phone 7 ComboBox

I am currently finishing off a tiny little WP7 application for a client here in New Zealand, which as such is not that very impressive. It seems like there is a LOT of apps on the way for the phone. I like it! At least the developers seem to have adopted the phone as their newborn child…or at least as a potential platform for future mobile apps…

But I am not going to be writing about that app. At least not right now. Instead, I wanted to write a little about something that surprised me. I have not been doing too much WP7 development. At least not the kind that includes a load of input controls. So I was kind of stumped when I found out that the phone does not have a ComboBox. Or rather, it does, but it doesn’t have a template suitable for the phone.

I found this to be rather odd, but could on the other hand understand that a ComboBox is probably not a control that is very well suited for a device like the phone. The OS itself seems to be using a list picker thingy instead, but that control seem to have stayed in Microsoft’s own control library and is not available. At least not that I have found.

So I guess the only solution is to do it yourself…at least after you Google it, which was what I did. I did find a couple of interesting ideas on how to style it, but they didn’t seem to follow the Metro style well enough to make me happy. Finally I found http://dotnet.dzone.com/articles/metro-style-combobox-windows, which got to act as the foundation for my control…

Luckily there is already a ComboBox available, so I thought I would just style it according to the Metro guidelines. Unfortunately, I ran into some issues that actually forced me to subclass the ComboBox.

The goal was to have a control that looked like this


It sort of mimics the list picker that Microsoft uses, but it does not expand in the same way. Instead, it uses a Popup to place the list of items on top of everything. In my situation that worked a lot better.

So…how much work is there to get this whole thing going? And how much code do we have to write? Well…to be honest, there isn’t a whole lot of code, but there is a bit of Xaml for the template…

The first thing to do is to create a project that can host the control (preferably a separate class library project for just controls so that they can be reused across several apps). After that, a Themes folder needs to be created, as well as a generic.xaml file.

It still annoys me that there is no way to add a templated control to a WP7 project. In Silverlight projects, this option creates all the basic stuff that you need and hook it up. Except for a tiny bug if you place your control class in another namespace than the default…but that is a discussion for another time…

After this is done, a class needs to be added. I have just simply called mine ComboBox as follows

using System;
using System.Windows.Shapes;
using System.Windows;
using System.Windows.Media;

namespace DarksideCookie.WP7.Controls
public class ComboBox : System.Windows.Controls.ComboBox
public ComboBox()
DefaultStyleKey = typeof(ComboBox);

There will be more code in there, but I want to cover the template first…

So the generic.xaml needs to look something like this before we can get started


<Style TargetType="local:ComboBox">
<Setter Property="Template">
<ControlTemplate TargetType="ComboBox">
<Border x:Name="WrapperBorder" />


As you might have noticed, there are 3 “non standard” namespaces in there. There is the “local” one that will contain the actual control, the vsm that is the namespace that contains the VisualStateManager and there is the System one that will give us access to system types.

The first thing I did, was to add the visual states from the dzone control I mentioned earlier

<Border x:Name="WrapperBorder" Padding="12">
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Disabled/>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused"/>
<VisualState x:Name="Unfocused"/>
<VisualState x:Name="FocusedDropDown"/>
<VisualStateGroup x:Name="ValidationStates">
<VisualState x:Name="Valid"/>
<VisualState x:Name="InvalidUnfocused" />
<VisualState x:Name="InvalidFocused" />

This Xaml is available in he download below. It was just too much mundane boring Storyboard code to put in the post… :)

As you might have seen, the Border has a Padding set. This is to make sure that the control gets and oversized hit area. Something that is defined in the Metro guidelines. It means that the control will react to “clicks” in a larger area than the control actually looks to be.

The control consists of two main pieces. The box and content that is shown when the control is collapsed, and the pop up that is shown when the control is expanded. The first one to look at is the collapsed UI.

It consists of a Border with a 2 pixel border in the correct color. And with correct color, I mean one coming from the built in static resources. Using these resources, makes it very easy to make sure that the control can handle both the light and the dark theme on the phone.

<Border x:Name="ContentPresenterBorder" BorderBrush="{StaticResource PhoneBorderBrush}" BorderThickness="2">


Yeah…I wrapped the whole thing in a Grid as the WrapperBorder only supports a single child…

Inside the Border, I placed a Grid. It was set up to have 2 columns. A “star” one and an “Auto” one. The “Auto” column will contain an optional arrow that can be shown and hidden by setting a property.

In the first column, a ContentPresenter is placed, with its Horizontal- and VerticalAlignment bound to the corresponding ContentAlignment properties. And in the second, the fabled Path of the shape of a downward arrow. The arrow is also given a big of a margin, and the Fill is once again set from one of the built in resources.

The Grid also contains a ToggleButton, which is the element responsible for getting the whole thing to actually expand. It has a ColumnSpan of 2, making sure that it covers the whole thing, even if the arrow is visible. And to make sure that the oversized hit area is working, the Margin on the button is set the to inverse value of the Padding on the WrapperBorder.

As I don’t want the ToggleButton to have a UI, but still work, I have replaced the Template with a transparent Grid.

<Border x:Name="ContentPresenterBorder" BorderBrush="{StaticResource PhoneBorderBrush}" BorderThickness="2">
<ColumnDefinition Width="Auto"/>
<ContentPresenter x:Name="ContentPresenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" IsHitTestVisible="False" />
<Path x:Name="BtnArrow" Data="F1 M 301.14,-189.041L 311.57,-189.041L 306.355,-182.942L 301.14,-189.041 Z " HorizontalAlignment="Right" Height="25" Margin="0,0,12,0" Grid.Column="1" Stretch="Uniform" Width="20" Fill="{StaticResource PhoneBorderBrush}"/>
<ToggleButton x:Name="DropDownToggle" Margin="-12" Grid.ColumnSpan="2">
<ControlTemplate TargetType="ToggleButton">
<Grid Background="Transparent" />

The next important part is the pop up. The thing that will display the list of items when the control is expanded. It is, as I mentioned several times, a Popup. The Popup, if you haven’t seen it, is a control that is rendered on top of everything. Making it the topmost UI element wherever it is placed in the Xaml.

Inside the Popup, I place a a Border. And since I want the list of items to be the same width as my control, I have bound the Width of the Border to the ActualWidth of the control. I have also given it a right side Margin that is twice the width of the Padding on the WrapperBorder. Making sure it gets the right size.

Inside of the Border, I have placed a ScrollViewer, which contains an ItemsPresenter. This should make sure that the content scrolls if it gets too big. However, it doesn’t really seem to work perfectly… So if you solve that, give me a yell…. Please!!!

I have also given the Popup a RenderTransform. The reason for this is that the Popup will by default end up below the containing element. But as I want it to cover it, I will use a CompositeTransform to translate transform it to the right position… More about this later…

<Popup x:Name="Popup" IsOpen="False">
<CompositeTransform x:Name="PopupTransform" />
<Border x:Name="PopupBorder" Padding="0,0,24,0" Width="{TemplateBinding ActualWidth}" BorderBrush="{StaticResource PhoneBorderBrush}">
<ScrollViewer x:Name="ScrollViewer" BorderThickness="2" Padding="0" Background="{StaticResource PhoneBackgroundBrush}" BorderBrush="{StaticResource PhoneBorderBrush}" Foreground="{StaticResource PhoneForegroundBrush}">

The template in the download contains a bit more Xaml as it also contains a DisabledVisualElement, FocusVisualElement and ValidationErrorElement. They do exactly what you would expect them to do based on their names. But I will not cover them in the actual post as it is fairly standard stuff…

The last thing to note in my ComboBox style is that I set the HorizontalContentAlignment and VerticalContentAlignment using two Setters. And I also add a new ItemTemplate. The ItemTemplate is very simple, as it just makes sure that there is a bit of padding in the list

<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="ItemTemplate">
<ContentPresenter Content="{Binding}" Margin="12" />


Ok…so that was the template. So all that is left is to write the code that is needed to get it going…

My ComboBox declares one new property called ShowArrow. This controls the visibility of the arrow in the UI. It is declared as a DependencyProperty. This is more because I want it to work nicely in the tools. Not so much to make it bindable…

public class ComboBox : System.Windows.Controls.ComboBox
public static readonly DependencyProperty ShowArrowProperty =
DependencyProperty.Register("ShowArrow", typeof(bool), typeof(ComboBox), new PropertyMetadata(false, OnShowArrowChanged));


private static void OnShowArrowChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
private void OnShowArrowChanged(DependencyPropertyChangedEventArgs e)
if (_btnArrow != null)
_btnArrow.Visibility = ShowArrow ? Visibility.Visible : Visibility.Collapsed;

public bool ShowArrow
get { return (bool)GetValue(ShowArrowProperty); }
set { SetValue(ShowArrowProperty, value); }


As you can see in the OnShowArrowChanged method, I am depending on a field called _btnArrow. The _btnArrow is supposed to be a reference to the Path that shows the arrow. However, since this is a templated control, I need to get a reference to it by hooking into the OnApplyTemplate method.

While I do this to get access to the arrow, I will take the opportunity to get a reference to the CompositeTransform for the Popup as well…

CompositeTransform _popupTransform;
UIElement _btnArrow;

public override void OnApplyTemplate()

_popupTransform = GetTemplateChild("PopupTransform") as CompositeTransform;
if (_popupTransform != null)
_popupTransform.TranslateY = -this.ActualHeight;

_btnArrow = GetTemplateChild("BtnArrow") as UIElement;
if (_btnArrow != null && !ShowArrow)
_btnArrow.Visibility = System.Windows.Visibility.Collapsed;

As you can see in the above code, I make sure to set the default values for those elements at the same time… There is now only one thing left to do, and that is to make sure that the Popup is re-translated if the control changes size. This is easy to do by listening to the SizeChanged event

public ComboBox()
DefaultStyleKey = typeof(ComboBox);
this.SizeChanged += (s, e) =>
if (_popupTransform != null)
_popupTransform.TranslateY = -this.ActualHeight;


That’s all there is to it! The only thing I have done on top of that, is to once again make sure it plays nice in the tools. And one thing that you should do to ensure this, is to declare any template parts that you access from code. This is done by using attributes

[TemplatePart(Name = "PopupTransform", Type = typeof(CompositeTransform))]
[TemplatePart(Name = "BtnArrow", Type = typeof(UIElement))]
public class ComboBox : System.Windows.Controls.ComboBox


As you see, I define the arrow path as a UIElement. This makes it possible to use any UIElement derived class to define it if the control is re-templated. Always go for the most generic type possible when declaring TemplateParts.

The different visual states should also be defined using TemplateVisualState attributes. These are however already defined on the base class, so we can skip that part… As well as the different TemplateParts that the base class uses and has already defined…

Code is available here: DarksideCookie.WP7.Controls.zip (43.35 kb)

Hope it has made your life a little bit easier not having to restyle the ComboBox on your own…


Comments (9) -

nice work man!
to get the scrolling to work i had to add the properties HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
to the scrollviewer, now it works for me.


good work
do you know how to set custom index to the item in control box
like <sys:string X:UID="x">item1</sys:string>
any thoughts

Hi Venu!
Is this for globalization? Or why do you need to set that?


First of all: very nice job on the ComboBox. I only have a little problem with it. I referenced your ComboBox in my project and I can add items and no errors occur when building and so on. When I start it up and see the ComboBox it looks like it should (www.dumpyourphoto.com/files2/52064/diKST.png) but when I click on it and it has to show the items, something goes wrong: I only see the last item. The weird part is that it actually shows all items but they're not visible only the last one (http://www.dumpyourphoto.com/files2/52065/koHY.png). I know the items are there because when I click somewhere in the dropped-down ComboBox I select another item (www.dumpyourphoto.com/files2/52066/5gYFnR.png).

Do you have any idea what may cause this? Because I've been looking a long time at this now.. Laughing

Thanks a lot in advance!
Kind regards,

Apparently the parentheses were included in the URL. The images are still available, you only have to remove the parentheses and the point. Sorry for this! ;)

Hi Abbas!
That is kind of interesting. I unfortunately haven't got time to look at it right now. But I would say that you are either getting black on black color in the template, or you have got some problems with your databindings.
On a separate note, this ComboBox will not be accepted in the Marketplace. It needs to override the back button and close the pop-up when it is clicked. Just found that out the hard way... Smile


Thanks for the quick response. I solved my problem with a ListBox, with some property changes I managed to accomplisch what I wanted.

But it is a shame that your ComboBox-solution is not accepted by the MarketPlace as I find it a very nice solution to get a Metro UI ComboBox. Nice job anyway! ;)

Hi Abbas!
Well, it should be accepted as long as you hook up the back button to close the drop-down. It is fairly easy to do, all you need is a back button override that looks at the IsOpen property (think that is the name). If it is open, close it, if not, let the back call bubble...
// Chris

Hi, I was searching and trying a lot of Metrostyle combos. Yours is the best, but...

I tried it on PotraitOrLandscape mode. Here the behaviour is totally confusing. You set y translation on OnApplayTemplate. This seems to be not enough since it doesn't work well in landscape mode while starting in protrait mode and vice versa. Also the width is not allways the width of the not droped down control. This is unfortunately the same behaviour as on the Silverlight control, so it is not your fault. On Silverlight no one changes the orientation.

And then try to change orientation while droped down. That's totally silly. I investigated allready a little into these problems, but without luck. Do you have any ideas?

Pingbacks and trackbacks (1)+

Comments are closed