ToolBar Buttons

For the ToolBar/RibbonBar in my hobby application I wanted to continue the trend of using “out-of-the-box” components and simply applying a style to give the correct look.

When placed within a ToolBar control the standard controls (Button, CheckBox, ComboBox etc.) all get a custom style applied giving them a “flat” appearance that suits a ToolBar. Overriding this style turns out to be very easy. Its simply a matter of creating a new style with the correct name. This is explained in the MSDN documentation here.

In practice it looks something like:

<TabControl Style=”{StaticResource RibbonBarStyle}”>
<Style TargetType=”{x:Type Button}” x:Key=”{x:Static ToolBar.ButtonStyleKey}”>



A common approach is to use the style to override the Template and remove the default Style (using OverridesDefaultStyle=”true”). Going down this path means that your style needs to cater for all button states, e.g. disabled, pressed, focused, mouseover etc.

Currently I’ve opted for a simpler alternative by using the Style to override only the ContentTemplate that defines the layout of just the content portion of the Button, rather than the entire Template.

So the XAML that I had been using to insert an image button into a ToolBar:

<Image Source=”/Images/film.png” Width=”48″/>
<TextBlock HorizontalAlignment=”Center”>Video</TextBlock>
<Button HorizontalAlignment=”Left”>
<StackPanel Orientation=”Horizontal”>
<Image Source=”/Images/folder24.png” Width=”24″/>
<TextBlock VerticalAlignment=”Center”>Open in Windows Explorer</TextBlock>


<Button Tag=”/Images/film.png”>Video</Button>
Button Tag=”/Images/folder24.png”>Open in Windows Explorer</Button>

For now I’m going to live with the image URI being stuck in the Tag property. Soon I plan on getting rid of the image and text references to be replaced with a single command reference, i.e. binding the command will set the image and text of the button in addition to the button enabled state, visibility etc.

The Style that I’m using is as follows:

<Style TargetType=”{x:Type Button}” x:Key=”{x:Static ToolBar.ButtonStyleKey}”> 
<Setter Property=”Margin” Value=”0″/>
<Setter Property=”Padding” Value=”0″/>
<Setter Property=”HorizontalAlignment” Value=”Left”/>
<Setter Property=”ContentTemplate”>
<DataTemplate DataType=”{x:Type Button}”>
<Border x:Name=”Border” CornerRadius=”4″>
<StackPanel x:Name=”PART_panel” Orientation=”Horizontal”>
<Image x:Name=”PART_image” Margin=”4,0,0,0″
Width=”{Binding RelativeSource={x:Static RelativeSource.Self},
=”{Binding RelativeSource=
RelativeSource FindAncestor, AncestorType=Button},
<ContentControl x:Name=”PART_text”
=”{Binding RelativeSource=
RelativeSource FindAncestor, AncestorType=Button},
=”Center” Margin=”3,0,4,0″/>
<DataTrigger Binding=”{Binding ElementName=PART_image, Path=Source.PixelHeight}”
<Setter TargetName=”PART_panel” Property=”Orientation” Value=”Vertical”/>
<DataTrigger Binding=”{Binding RelativeSource=
RelativeSource FindAncestor, AncestorType=Button},
<Setter TargetName=”PART_panel” Property=”Opacity” Value=”0.5″/>
<Setter TargetName=”PART_text” Property=”HorizontalAlignment” Value=”Center”/>

The images themselves are shown using the native resolution. You would have thought Stretch=”None” might have done that – but don’t be fooled. For reasons relating to DPI scaling you have to set either the Width or Height to an absolute value. I used the Binding {Binding ElementName=PART_image, Path=Source.PixelHeight} to achieve that.

One trick I did do here is use a Data Trigger to change the placement of the text in relation to the image based on the size of the image that is used. Its a little clunky but I’m using images that are either 16, 24 or 48 pixels sqaure. The 16 and 24 pixel sqaure images have the text positioned to the right of the image. For 48 pixel square images the text is positioned underneath.

So the following XAML:

<TabItem Header=”Hello”> 
<ToolBar Header=”Hello World, I’m a Ribbon Group”>
<Button Tag=”/Images/note_edit_48.png”>Write Entry</Button>
<Button Tag=”/Images/users_family_24.png”>Maintain Users</Button>
<Button Tag=”/Images/folder_24.png”>Open in Windows Explorer</Button>
<Button Tag=”/Images/weather_48.png”>Record Weather</Button>
<ToolBar Header=”Second Group”>
<Button Tag=”/Images/film_48.png”>Video</Button>
<Button Tag=”/Images/earth_location_24.png”>Maintain Locations</Button>
<Button Tag=”/Images/money2_24.png” IsEnabled=”False”>Maintain Currencies</Button>
<Button Tag=”/Images/presentation_24.png”>Slideshow</Button>

Generates the following styled TabItem within a parent TabControl.

XAML Ribbon with Button ContentTemplate Style

The buttons lay themselves out nicely arranged automatically from left to right because I’ve set the ToolBar’s ItemsPanel to be a fixed height WrapPanel:

<WrapPanel Orientation=”Vertical” Height=”70″/>

If you want to customise the button more – for example to give it an orange gradient mouse over effect then you’ll need to override the Template rather than ContentTemplate in the Button Style.

[Updated 24-Mar-2008 to use ContentControl instead of TextBlock in the ContentTemplate to allow for Buttons that wanted full control of their own content.]

One thought on “ToolBar Buttons”

Comments are closed.