Click here to Skip to main content
Click here to Skip to main content
Go to top

WPF: IconButton

, 20 Nov 2009
Rate this:
Please Sign up or sign in to vote.
Creating a little push button from an icon
The demo application comparing a normal button with the IconButton

Introduction

While there are a few demo videos on how to create nice buttons with Expression Blend, I didn't find a straight forward description on how to create a nice button from an image. This article tries to fill this gap and a bit more. The IconButtonStyle takes the contents of the button, decorates them with a little shadow and when the user presses the button, it generates a subtle animation "pushing" the content into the screen.

Background

Styles are XAML's way of collecting common properties into a reusable definition. Usually styles are defined in the Apps.Resources or Window.Resources section of XAML.

An in-depth discussion of the presented material can be found in the Customizing Controls For Windows Presentation Foundation article of the MSDN Magazine.

Using the Code

The attached demo project has a single window with a few controls to exercise and inspect a normal Button and compare it to the created icon Button. If you want to use this in your own project, the relevant styles and resources for the icon Button are all collected in the App.xaml's Resources section. There, you will find the original styles generated by Expression Blend 2 (September Review) and the Style I wrote.

To use the style, just copy the whole IconButtonStyle from the App.xaml into your own Resources and set the Style property of your button to "{DynamicResource IconButtonStyle}". Although the style was primarily designed to contain items, the Button's contents can be any XAML element you choose.

<Button Style="{DynamicResource IconButtonStyle}">
    <Image Source="/WpfIconButton;component/Icons/Symbol-Add.png" />
</Button>

Points of Interest

The general structure of the style looks like this:

<Style x:Key="IconButtonStyle" TargetType="{x:Type Button}">
    <!-- set default values -->
    <!-- set the visual tree of the control -->
    <Setter Property="Template">
        <Setter.Value>
        <ControlTemplate TargetType="{x:Type Button}">
                <!-- here come the actual sub-controls -->
        <ControlTemplate.Triggers>
            <!-- the triggers define the reactions to various state
                         changes -->

Most of the interesting logic happens within the triggers, which -- amongst other things -- modify the "translation" RenderTransform and the "shadow" Effect on the ContentPresenter to create the "push" effect. Here are the relevant parts of the ControlTemplate:

<ContentPresenter ... >
    <ContentPresenter.Effect>
        <!-- give the content a bit of shadow -->
        <DropShadowEffect x:Name="shadow"
            ShadowDepth="2"
            Opacity="0.7"
            BlurRadius="3" />
    </ContentPresenter.Effect>
    <ContentPresenter.RenderTransform>
        <!-- push the content a bit to the left and the top -->
        <TranslateTransform x:Name="translation"
            X="-1" Y="-1"/>
    </ContentPresenter.RenderTransform>
</ContentPresenter>
<ControlTemplate.Triggers>
    <Trigger Property="IsPressed" Value="True">
        <Trigger.EnterActions>
            <BeginStoryboard> <Storyboard>
                <DoubleAnimation
                    Duration="0:0:0"
                    To="0"
                    Storyboard.TargetName="shadow"
                    Storyboard.TargetProperty="(DropShadowEffect.ShadowDepth)"/>
                <DoubleAnimation
                    Duration="0:0:0"
                    To="0"
                    Storyboard.TargetName="translation"
                    Storyboard.TargetProperty="(TranslateTransform.X)"/>
                <DoubleAnimation
                    Duration="0:0:0"
                    To="0"
                    Storyboard.TargetName="translation"
                    Storyboard.TargetProperty="(TranslateTransform.Y)"/>
            </Storyboard> </BeginStoryboard>
        </Trigger.EnterActions>
        <Trigger.ExitActions>
            <BeginStoryboard> <Storyboard>
                <!-- The ExitActions StoryBoard reverses the made changes -->
            </Storyboard> </BeginStoryboard>
        </Trigger.ExitActions>
    </Trigger>
</ControlTemplate.Triggers>

Acknowledgements

History

  • 2008-02-07: First version released
  • 2009-11-20: Updated to use H/W accelerated effect instead of BitmapEffect

License

This article, along with any associated source code and files, is licensed under The BSD License

Share

About the Author

DavidSchmitt
Founder http://dasz.at/ -- Software for Humans
Austria Austria
No Biography provided

Comments and Discussions

 
GeneralBitmapEffect! PinmemberBeepcake12-Oct-09 1:31 
AnswerRe: BitmapEffect! PinmemberDavidSchmitt19-Nov-09 23:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    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 | Mobile
Web02 | 2.8.140905.1 | Last Updated 20 Nov 2009
Article Copyright 2008 by DavidSchmitt
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid