RoundedButton Button Style (WPF)

So far, I have only one style which I'm currently using on all my buttons, and to be honest, I'm still working on it, but it's been in a pretty stable state of development for a while now, so I thought I'd share it.

Let me introduce you to the imaginatively titled: RoundedButton.

Buttons with no hover, click etc.

The above picture shows 3 buttons, the first (top-most) is the bog standard WPF button, no styles applied.
<Button Height="30" Width="100" Margin="20">Normal Button</Button>
The second two are RoundedButton styled, with different background etc settings:

   1:  <Button Height="30" Width="100" Margin="20" Style="{DynamicResource RoundedButton}" Background="#FF7F90FC" BorderBrush="#95FFFFFF">RoundedButton</Button>
   2:  <Button Height="30" Width="100" Margin="20" Style="{DynamicResource RoundedButton}" BorderBrush="#83FFFFFF">
   3:    <Button.Background>
   4:      <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
   5:        <GradientStop Color="#FF000000" Offset="0"/>
   6:        <GradientStop Color="#15FFFFFF" Offset="1"/>
   7:      </LinearGradientBrush>
   8:    </Button.Background>
   9:    RoundedButton
  10:  </Button>


OK, so what else (aside from change a button to be round cornered) does the RoundedButton style give us?
Well, first, there's the traditional 'hover' look
Middle button with MouseOver Bottom button with MouseOver

and then, we have the 'Clicked' look, which in this case involves a ScaleTransform of 0.9 for both the X and Y values.. so, a 10% decrease in size across the board, as shown below:

Bottom button with Click

How do you use it? Firstly you need the ResourceDictionary, (it's at the bottom of this post, still can't figure out how to attach code.. or indeed if that's possible!), then you need to add a reference to it in either the App.xaml file, or just the Window / Control etc xaml file you want the button to be visible in. We do that - like this:

<ResourceDictionary>
  <ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="RoundedButton.xaml"/>
  </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>


To 'style' a button we then add the following to the button declaration:

Style="{DynamicResource RoundedButton}"


Now you have a standard RoundedButton, but you might want to style it more, change the background etc? Well, just like a normal button, just edit the properties of the button. The only property that doesn't do what you might expect is the 'BorderBrush' and that's because I nabbed it to act as the 'MouseOver' brush.

i.e. when the mouse is over the button, the colour that fades in the bottom half of the button is the BorderBrush.

Erm, I don't think there's anything else to add really...

Feel free to make changes to any of the code, it's free to all! (Though I'd like to know, I always like to improve my code as well :))



<!-- RoundedButton.xaml -->
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
    <Style x:Key="ButtonFocusVisual">
        <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate>
                    <Border>
                        <Rectangle SnapsToDevicePixels="true" Margin="4" Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
 
    <Style x:Key="RoundedButton" TargetType="{x:Type Button}">
        <Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
        <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="BorderThickness" Value="3"/>
        <Setter Property="HorizontalContentAlignment" Value="Center"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Padding" Value="0,0,1,1"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <ControlTemplate.Resources>
                        <Storyboard x:Key="ShowShine">
                            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Shine" Storyboard.TargetProperty="(UIElement.Opacity)">
                                <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1"/>
                            </DoubleAnimationUsingKeyFrames>
                        </Storyboard>
                        <Storyboard x:Key="HideShine">
                            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Shine" Storyboard.TargetProperty="(UIElement.Opacity)">
                                <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>
                            </DoubleAnimationUsingKeyFrames>
                        </Storyboard>
                    </ControlTemplate.Resources>
                    <Border CornerRadius="5,5,5,5" BorderThickness="1,1,1,1" RenderTransformOrigin="0.5,0.5" x:Name="border" BorderBrush="#FFFFFFFF">
                        <Border.RenderTransform>
                            <TransformGroup>
                                <ScaleTransform ScaleX="1" ScaleY="1"/>
                                <SkewTransform AngleX="0" AngleY="0"/>
                                <RotateTransform Angle="0"/>
                                <TranslateTransform X="0" Y="0"/>
                            </TransformGroup>
                        </Border.RenderTransform>
                        <Border Background="{TemplateBinding Background}" CornerRadius="5,5,5,5" x:Name="border1">
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="0.5*"/>
                                    <RowDefinition Height="0.5*"/>
                                </Grid.RowDefinitions>
                                <Border Grid.Row="0" CornerRadius="5,5,0,0">
                                    <Border.Background>
                                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                            <GradientStop Color="#00FFFFFF" Offset="0"/>
                                            <GradientStop Color="#7EFFFFFF" Offset="1"/>
                                        </LinearGradientBrush>
                                    </Border.Background>
                                </Border>
                                <Border Grid.Row="1" Opacity="0" x:Name="Shine" Width="Auto" Height="Auto" CornerRadius="0,0,5,5" Margin="1,0,-1,0" Background="{TemplateBinding BorderBrush}"/>
                                <ContentPresenter VerticalAlignment="Center"  Grid.RowSpan="2" HorizontalAlignment="Center" x:Name="contentPresenter"/>
                            </Grid>
                        </Border>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter Property="Opacity" TargetName="border1" Value="0.5"/>
                            <Setter Property="Opacity" TargetName="border" Value="1"/>
                            <Setter Property="Opacity" TargetName="contentPresenter" Value="0.5"/>
                        </Trigger>
                        <Trigger Property="IsPressed" Value="True">
                            <Setter Property="RenderTransform" TargetName="border">
                                <Setter.Value>
                                    <TransformGroup>
                                        <ScaleTransform ScaleX="0.9" ScaleY="0.9"/>
                                        <SkewTransform AngleX="0" AngleY="0"/>
                                        <RotateTransform Angle="0"/>
                                        <TranslateTransform X="0" Y="0"/>
                                    </TransformGroup>
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Trigger.ExitActions>
                                <BeginStoryboard Storyboard="{StaticResource HideShine}" x:Name="HideShine_BeginStoryboard"/>
                            </Trigger.ExitActions>
                            <Trigger.EnterActions>
                                <BeginStoryboard x:Name="ShowShine_BeginStoryboard" Storyboard="{StaticResource ShowShine}"/>
                            </Trigger.EnterActions>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

Print | posted @ Friday, June 20, 2008 11:27 AM

Comments on this entry:

Gravatar # re: RoundedButton Button Style (WPF)
by Anonymous at 7/15/2009 8:30 AM

This is pretty sweet!

I easily modified the code to satisfy my needs, and the button looks great.

Thanks for posting the code!
Gravatar # re: RoundedButton Button Style (WPF)
by Vikas Bhandari at 7/17/2009 8:39 AM

Excellent. I was looking for this only.
Gravatar # re: RoundedButton Button Style (WPF)
by kene at 11/25/2009 2:41 AM

Hello,can you share your sourcecode to me please?

Thanks!

CHOUKEI@LIVE.CN
Gravatar # re: RoundedButton Button Style (WPF)
by Chris at 11/29/2009 1:47 AM

The code is already there!
Gravatar # re: RoundedButton Button Style (WPF)
by TMC at 5/20/2010 2:01 PM

Very Nice!
Gravatar # re: RoundedButton Button Style (WPF)
by Nurav at 10/9/2010 8:06 AM

buddy u have just written a code not explained it.......
then 2 its awesome :)
Gravatar # re: RoundedButton Button Style (WPF)
by Andy at 8/4/2011 5:01 PM

Hi,
Can I translate this article for Korean?
Gravatar # re: RoundedButton Button Style (WPF)
by El_Bouriqueto at 8/24/2011 9:35 PM

yeeeeeeeeeeeeeeeee!
thx
Gravatar # re: RoundedButton Button Style (WPF)
by Sudeep at 2/2/2012 10:09 PM

Hi,
That was really helpful....code explained in simplest possible language :)

Cheers !!!
Gravatar # re: RoundedButton Button Style (WPF)
by julien at 9/11/2013 2:49 AM

hi really like your buttons, couple of things

the gradient color split in the middle of the button is really glaring. maybe you could smooth out the color transition with a couple more gradients?

second thing. the mouse over color sticks out the right side of each button by a couple pixels.

thanks again!
Gravatar # re: RoundedButton Button Style (WPF)
by Chris at 9/11/2013 8:25 PM

@Julien

In 2008 this colour split effect was all the rage, just do a quick search for 'Vista Buttons' in your favourite search engine. The 'split' you are referring to is a light gradient that ends halfway down the button (x:Name of 'Shine' I believe) so - you could decrease the opacity at the bottom, which would give you a much smoother look, if you were designing them from scratch, you would probably not make them look like this anymore - especially with the flat design fad of the moment.

I can't see the second point, but feel free to play around with the xaml as much as you want, it's all there!
Gravatar # re: RoundedButton Button Style (WPF)
by Michael at 1/20/2014 1:59 PM

Thanks a lot
Gravatar # re: RoundedButton Button Style (WPF)
by Gareth White at 11/23/2015 3:11 PM

this is fairly easy to do from code behind using the existing border with the default button template as follows. (You can find the FindVisualChild method anywhere on the web).

Dim l_Border As Border = FindVisualChild(Of Border)(THIS_BUTTON)

If Not IsNothing(l_Border) Then l_Border.CornerRadius = New CornerRadius(CORNER_RADIUS)
Gravatar # re: RoundedButton Button Style (WPF)
by Milivoje at 5/13/2016 3:43 PM

That was really helpful..thanks
Post A Comment
Title:
Name:
Email:
Comment:
Verification: