Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WPF

Building Better Buttons in Expression Blend and Silverlight

4.90/5 (127 votes)
3 Apr 2010CPOL62 min read 2   2.2K  
Beginner's guide to building robust, scalable, and easily editable buttons
This is a beginner's guide on how to build robust, scalable, and easily editable buttons, as well as covering Template Binding to the Style, Layout, Animation, Opacity Masks, Scalability, and Reuse.

Introduction

Do all buttons have to look so traditional? Not in Silverlight!

ExpressionBlendButtons/IntroA..jpg

ExpressionBlendButtons/IntroB..jpg

We can now make them beautiful thanks to the power of Silverlight and Blend, shown wonderfully by Timmy Kokke in his Glass Orb Button article. But we can do more than just colourful, so I'd like to share some ideas for how we can go a bit further. As well as discussing how to build your buttons with consideration to: Layout, Styles, Animation, Scalability, and Reuse.

So if you are a developer looking to improve your artistic skills, a designer who is new to the Expression Blend environment or just struggling with the concepts of Expression Blend, then this may be for you, or for someone on your team!

Background

There are many articles online about making buttons, be it in Photoshop, Illustrator, CorelDraw, etc., and these can be found by simply searching for "glass button" in Google Images. And these can provide inspiration, but most importantly: almost all the principles can be applied to Silverlight using Expression Blend and Expression Design. So rather than focusing on re-creating a specific button parrot fashion, my aim will be trying to help you get the best out of Expression Blend for your own individual creations. Expression Blend and Silverlight are not just a vector artwork package, with bits bolted on. It is so much more, and requires a slightly different way of working. As well as extra considerations when designing artwork for applications. So I will try to guide you in making robust buttons (UserControls), with principles that can be applied anywhere in the Blend environments, discussing things like "Scalability", will your button look good and function correctly at all resolutions, etc. Some of the techniques and operations you may want to apply will not scale, like Margins and Strokes, as well as Effects like Blur and Drop Shadow. Hopefully, I can steer you on a path to avoid some painful errors, building clean flexible controls that work well and as expected.

Overview

In this tutorial, I will be covering everything to recreate the first button shown in the introduction image above. I will be approaching this tutorial from the perspective of a Designer who understands vector artwork, but with no knowledge of Silverlight or Expression Blend. I will attempt to document every step at the start, hopefully speeding up as we go along to prevent it becoming tedious. Meaning, if you are new to Silverlight and Expression Blend, I would recommend you do not skip sections. This tutorial will also act as a pre-requisite to any further tutorials I do.

I have sub-divided the tutorial into sections for easier reference:

  1. Basic Button, Layout, and Components
  2. Modifying the Button
  3. Scalability Issues
  4. Cosmetic Surgery
  5. Interaction and Animation
  6. Multiple Colours and Final Touches
  7. Focused, Disabled, and Content

Section 1 - Basic Button, Layout, and Components

Open a new Silverlight project in Expression Blend and call it something like "TestButton". Select the Button icon in the left hand tool bar.

Image 3

Now place a button on the screen, by either dragging the desired button size and location on the Artboard (centre layout panel), or by double clicking on the Button icon. Try each method and see the different results. Now let's consider what size the button should be and what is controlling the size of your button. And how this differs from a vector artwork package.

The Artboard provides some manipulation and control over the size of your button and its relationship to its parent. But I would like you to focus on the Layout section of the Properties tab on the right to control your button.

Image 4

Take a look at the white dots that appear on the right of each setting, this is an indicator that the setting is not "Default". Now these dots are also buttons, so click on each white dot in the Layout section of the Properties tab and select "Reset".

Image 5

Notice how your button changes to eventually fill the LayoutRoot. (Its parent object is in the Objects and Timeline tab.) In Blend, it is always desirable to have your Objects (Controls) to dynamically resize and stretch to fit its parent Object.

Rather than defining absolute values, like fixed Width and Height, it's better to allow the parent object to control the size of your Object. Select LayoutRoot in the Objects and Timeline and change its size in the Layout section of the Properties tab. See how this controls and defines the size of your button.

Set the LayoutRoot back to its defaults, by using the small white buttons and selecting "Reset". Now we wouldn't want the button to completely fill our screen, and we can control the button's size within the parent object (LayoutRoot) using Margins. So with the button selected in Objects and Timelines, enter some values for the Margins, or drag the edges of the button in the Artboard.

Image 6

(Values can be negative, as well as positive.)

I won't discuss Horizontal and Vertical Alignment at present, other than saying they should both be set to Stretch, which is the default setting, so use the Reset feature. It's important to understand that fixed Width and Height is generally bad, unless it is the "Root Object".

In Objects and Timeline, click on "[UserControl]" and notice it has a fixed size of 640x480 (not auto sized). This is the "Root Object", the parent to all the child elements/objects that make up this Object (or UserControl).

Everything (all children) should take instructions on how to layout from the parent, only it should have a fixed size.

So to summarise, I hope you understand that there are two basic ways we control the size of an object:

  1. Fixed Width and Height: Button will not scale when the parent object resizes.
  2. Auto sized Width and Height with Margins set: Button will scale with parent object.

There are more, which we will introduce later...

Now select your button in Objects and Timeline, and Reset all the Layout properties of your button back to their defaults. Set the Width and Height to 100x100 pixels (fixed size). I know I said it is bad to use fixed Width and Height, but for our purposes here, the button will be our "Root Object". (It will control the size of all the child items we are going to play with.)

Now right click on your button and choose Edit Template > Edit a Copy. You should be presented with a window named "Create Style Resource". Give this Style Resource (a button Style) a name like "ButtonRound1" and select OK.

Image 7

(Don't worry about what you call it, as it can be changed in the Resources tab later, and all the references to it will automatically be updated.)

Hopefully, you will have spotted that in getting in to the button Template, we had to create a button Style. So what is the difference? Basically, a Style should hold the general properties of the UserControl (button), things like Colour and Text should be controlled in the Style. The Template is the bits and pieces that make up the control (Button), and inherits properties like Colour and Text from the Style using Template Binding.

It would not be desirable to have to change the colour of all the Template components, which could be numerous, when it can be done in a single click in the Style!

Styles can be compiled in to Resource Dictionaries, which your developer may request, and this can be done at anytime, using drag and drop in the Resources tab.

But let us move on with our button and have a look at exactly what is the "Button Template". In the Objects and Timeline tab, we can see a breakdown of all the components/bits that make up a button.

Image 8

I've expanded that grid to expose the child objects, and for clarity, I will refer to the parts that make up the template as elements. Before we delete most parts/elements of the template, let's have a quick look at what we have and how it works. It is composed mostly of Grids and Rectangles which have Colour properties applied to them. As well as a Content Presenter, which is a place holder to display Content specified in the root of the object, or defined at runtime by the developer.

There are also two Border item/elements which have similar properties to a Rectangle, but basically has more control over its edge and corner properties. In the Template, select the Grid directly above the BackgroundAnimation element. Now look at the Properties tab on the right hand side and you will see that the background colour has a small orange dot next to it on the right side.

Image 9

There is also an orange rectangle around the colour picker. These indicators signify that the background colour is Template Bound to the Style and should not be changed here. Instead, we should edit the Style if we want to change this colour.

To edit the Style, click on the Style icon (looks like a pie chart, cheese, or Packman) in the top left corner of the Artboard.

Image 10

All the components/elements in the Objects and Timeline tab will disappear, and will be replaced with "<>Style" to signify that we are in the Style.

Image 11

Now in the Style, go to the Properties tab and change the background colour to bright red. Go back into the Button Template, by clicking on the Grid node to the right of the Style icon.

Image 12

Now the element named Grid in the Objects and Timeline tab should be automatically selected.

Look again at the Background colour in the Properties tab to see if it has changed. (Hopefully, it will be bright red.) If you hunt about, you will see that the BorderBrush of the Style, is Template Bound to the BorderBrush of the element named Background. As is the BorderThickness, allowing us even more manipulation of how the UserControl (Button) will look, just by modifying the Style.

But we cannot control everything from the Style and to pull out every Resource would be excessive and unwieldy. For example, we cannot easily control or reference the MouseOver colour States in the Style and I will explain why later.

Select the BackgroundGradient element in Objects and Timeline and have a look at the Background Fill colour.

Note that it is a white gradient, with changes in its Alpha (opacity/transparency) at four Gradient Stops along the Ribbon.

ExpressionBlendButtons/img19.jpg

This allows the solid block colour of the element underneath it BackgroundAnimation to show through in the form of a coloured gradient. And the principle of applying overlays to a solid block colour can be very powerful, as well as easy to edit or reference by the Style or a Colour Resource.

Now let's look at how the button changes its appearance for different States, like RollOver, Pressed, and Disabled. Ensure you are on the States tab (top left corner) and select the MouseOver state. Now expand all the elements in the Objects and Timelines tab. Click the "Show Timeline" icon to the right of "MouseOver" in the Objects and Timeline tab.

Image 14

Note that there is now a red border around the Artboard and that some blue Keyframes have become visible in the Objects and Timelines tab. (Keyframes are points that define a change or a fixed value at a certain point in time. By default, these will occur instantly at time zero.) Select the BackgroundAnimation element and look at the Opacity value in the Property tab, see that it is set to 100%. Now change the States Manager back to "Base" and see that the Opacity is now set to 0%.

The BackgroundGradient element also changes, as the Alpha (Opacity) of three of the four Gradient Stops is reduced. This allows the background colour to show through more in the lower half, but not in the top half. Investigate and play with the different states, but remember to use the Base state to create and modify your elements, as this defines the default properties or starting point for all other States before you modify them. (You can work in the "Base" state and simulate another by clicking on the eye icon to the left of that state.)

Hopefully, you have realised that DisabledVisualElement and FocusVisualElement are just overlays and borders (Stroke), respectively.

One last thing before we start modifying our default button. Earlier when I spoke about what defines the size of a button, I ignored, for simplicity, something else that can define the size of a button. What would happen if I told the button to only be as large as it needs to be? To do this, you will firstly need to come out of the Button Template. Either by clicking the "(Button)" node in the top of the Artboard:

Image 15

Or the "Return Scope" icon in Objects and Timeline.

Image 16

Now change the Layout properties in the Properties tab as shown:

Image 17

Ensuring all properties are Reset, except for the Horizontal and Vertical Alignment, which are both set to Centre. The button will shrink to a size, just large enough to accommodate the contents (plus a little bit, which is called Padding). Increase the Font Size to say 48pt, and see how this affects your button. Go into the Style for the button, and in the extended attributes of Layout in the Properties tab, you will find an option for Padding.

Alternatively, just type "padding" into the search at the top of the Properties tab.

Image 18

Now change the values to 40 and see how this affects the size of the button.

Image 19

If you want to see how the Padding is set, look in the Properties tab of the ContentPresenter inside the Button Template. (Remember to clear the search to unhide the properties that do not fit the search in the Properties tab.)

The Margin property is Template Bound to the Padding property of the Style.

Image 20

So when I define a Padding change in the Style or outside of the Button Template, it is actually the Margin of the ContentPresenter inside the Button Template that we are controlling. At the risk of labouring the point, I'm trying to show the function of Styles. As well as hopefully demonstrating that the initial designer may not have final control over the size of the button. It can depend on the Size and Layout of your page, as well as the Content defined within it.

So I recommend you consider ensuring your work functions correctly at all sizes!

Section 2 - Modifying the Button

So we have looked at the different elements that make up a default button, and we could manipulate the elements we have. Instead, let us Delete everything else, except the ContentPresenter. Don't worry about the warning message that the animations will be lost.

Image 21

(This is because we are removing elements that have animations applied to them.)

We are now left with the basic shell of a button, with a Template consisting of an element of type Grid and a child element of type ContentPresenter. Why do we have a Grid as the Root element? Because Grid it is the best Layout Container for formatting (controlling) the layout of child elements. Not only can Grid contain multiple children, it can be subdivided to constrain the proportions and layout of the child elements. We will be using Grid to group elements that apply to a specific part of a button, like "Rim", or "Face" for example.

So let's get started and create a round button with a Rim. Select Grid in the Objects and Timelines tab. Then click and hold the Rectangle tool in the toolbar on the left to reveal the Ellipse tool.

Image 22

With the Ellipse icon on the toolbar, double click it, and an Ellipse will appear as a child element of the Grid element.

Image 23

If you have been following from the beginning, your Artboard should look like this. The Ellipse does not fill the whole area of the button, instead it is inserted at a size of 100x100 pixels in the top left corner. This is because, even though the button would like to be 100x100 pixels, the ContentPresenter is controlling the size of the button due to the Layout, Font Size, and Padding changes we previously set for the button. Come out of the Button Template by using the Up Scope icon in Objects and Timelines, and Reset the Font Size from 48 to 8.25. Notice how the button shrinks, and what was a circle is now a squashed ellipse.

Image 24

Next give the button a fixed Width and Height of 100x100 pixels.

Image 25

The text now does not display properly, due to the excessive Padding we set in the Style. But the ellipse now spans the width of our button, which is what we want. So go to the Style, using the Style icon.

Image 26

Now in the extended properties of the Layout section, Reset the Padding back to the Default value of 3. Now the text displays properly, but the ellipse is still not a circle. So select the Ellipse using the icon to the right of the Style icon, to enter the Button Template.

Image 27

(It may say "ContentPresenter", and will depend on what was the last selected element in Objects and Timeline of the Button Template.)

Ensuring you have the Ellipse selected, look at the Layout properties in the Properties tab for the Ellipse. Notice that we have settings applied that we did not set.

Image 28

This was Expression Blend trying to insert an Ellipse to fill the Button Template, which it thought was 100x100 pixels. But the ContentPresenter was controlling the size of the Button Template, making it larger, so the Layout just did the best it could.

That may be a little confusing, but when working at design time, set a Fixed Size for the parent object (button) and set the children to automatically fill it. Reset all the defaults of the Ellipse in the Layout section of the Properties tab. (Or delete the Ellipse and double click the Ellipse icon on the left tool bar to insert a fresh Ellipse.)

Hopefully, you have an Ellipse element and a ContentPresenter element.

Image 29

In the Artboard, the button text is no longer visible as it is obscured and behind the Ellipse. Click on the "Eye" icon next to each element to show or hide what is behind it. (In Photoshop, layers build from the bottom up; in Expression Blend, they build from the top down.)

So select the ContentPresenter element and drag it below the Ellipse and therefore in front of the Ellipse, as we are always going to want the ContentPresenter in the front. But every time we add a new element, it is positioned at the bottom of the list and therefore in front of the ContentPresenter. To avoid this annoyance, we will build the framework of our button in its own dedicated Grid.

Right click on the Ellipse and select Group Into > Grid.

Image 30

Now rename the newly created Grid and call it "Rim".

Image 31

Now select the Ellipse and duplicate the Ellipse by using the keys "Ctrl +C", "Ctrl +V" (Copy and Paste). You should now have two Ellipses within the Grid called Rim and no problem with the ContentPresenter being covered.

Now is a good a time as any to start naming our components/elements.

So select the top Ellipse in the list and call it BGround, then select the bottom Ellipse in the list and call it RadialGradient.

Image 32

With the Ellipse element named BGround selected, and using the Advanced Properties button, change the Fill property to Template Binding > Background.

Image 33

This will set the Fill of our Ellipse and therefore the overall colour of our UserControl editable from the Style of our UserControl. (We can't see any results or colour change yet, because we have another Ellipse named RadialGradient on top).

Click on the "Eye" icon of the RadialGradient element to show the Fill (Background) colour of the Style.

Image 34

If you have not changed the Background colour of the Style, your button should look like this:

Image 35

Very boring, so let us set the RadialGradient element as an overlay, to control the Opacity and Tone of the Background colour below.

Select the RadialGradient element and in the Properties tab, change its Fill to "Gradient Brush".

Image 36

Next, change the gradient from Linear to Radial.

Image 37

Now set both Gradient Stops on the Ribbon to White, and position like mine at locations: 85, 90, 95, and 100 on the Ribbon.

Image 38

(Click anywhere in the Ribbon to add another Gradient Stop and drag off the Ribbon to remove to a minimum of 2).

Next, set the Gradient Stop at Ribbon location 85 to have an Alpha (Transparency) of 0%. Repeat the above step for the Gradient Stop located at 100 on the Ribbon. This should give you a button looking like this:

Image 39

Not very pretty yet, but you can see the Rim forming. Zoom in on your button and see that we have an annoying black line on the outside edge. This is getting in the way of our gradient, which is the "Stroke" of both Ellipses. So let's get rid of it. Select Stroke for each Ellipse and set to "No Brush".

Image 40

The Rim is starting to look better, but the contrast is rather strong. We can adjust this by either adjusting the Alpha of the Gradient Stops at 90 and 95 on the Ribbon to say 60%:

Image 41

Or by adjusting the Opacity of the whole element.

Image 42

My preference at the moment is to make the adjustment in the Gradient Stops, as it allows simpler control for adjusting the whole element between 0% and 100%. (Or does it? We will discuss that later...)

Moving on, we want our Rim to sit around the outside of our button Face. I want the page colour to show through on the inside edge of the Rim. So I will change my page colour to a horrid red for demonstration purposes. Use the Return Scope icon to come out of the Button Template. And change the Fill colour of the LayoutRoot element to Red.

Image 43

Now to make the centre of the Rim transparent, we can use an Opacity Mask. And we could set an Opacity Mask on both Ellipses. (But I'd like to save them for some further effects I might wish to apply).

Instead, I'm going to apply it to the parent object of the Ellipses: the Grid element named Rim, as it also supports an Opacity Mask. So select the button in Objects and Timeline and go back in the Button Template. Select the Grid element named Rim; in the Properties tab, select Opacity Mask. Give it a Radial Gradient, with Gradient Stops at 0, 84, and 85 on the Ribbon.

Image 44

Set the Alpha to 0% for the 0 and 84 Gradient Stops, and 100% for the 85 Gradient Stop. (The Gradient Stop at 0 is not actually needed, but left in for clarity.) The inner 85% of all the elements that make up your button Rim are now invisible.

Image 45

Test it by changing the Fill colour of the "LayoutRoot" Grid. (Remember that you are in the Button Template and need to press Return Scope to manipulate the "LayoutRoot" Grid colour).

Now back in the Button Template, we will start creating our button Face to sit inside the Rim. Ensure you have the Grid element named Rim selected. Double click on the Ellipse icon in the left tool bar, which inserts a new Ellipse inside of the Grid named Rim. This is not going to work for us, as the inner 85% of the Ellipse is missing. This is because, it is being controlled by the parent object, the Grid element named Rim, which has an Opacity Mask applied to it, and as such affects all of its child elements. So we need to move it out of the parental control of the Grid element named Rim.

Select the Ellipse in Objects and Timeline and drag it on to the element named "[Grid]". (Notice how the Ellipse now sits in front of the ContentPresenter).

Select the ContentPresenter and drag it to the bottom of the list.

Image 46

Now select the Ellipse, right click and choose Group Into > Grid. Rename the newly created Grid and call it Face. Select the child Ellipse element and rename it "BGround1".

Image 47

(Notice that two elements/components cannot share the same "X" name!).

Now to make the Face the same colour as Rim: Template Bind the Fill colour of the BGround1 element to the Background colour of the Style.

Image 48

We cannot see the Rim in the Artboard, because it is obscured by the newly created Face.

Image 49

We need to reveal the Rim area as well as a clearance gap between the Rim and the Face. From what I have shown you so far, we could apply an Opacity Mask to the Face. That is inverse/opposite of the Opacity Mask on the Rim. But this would mean is only the central 85% of the child elements of the Face would be visible. (Awkward, and no good if we ever want to use the Stroke of a child element).

Margin could be another method of controlling the size of the Face. Select the Grid element named Face, and set the Margin to 10 on all sides.

Image 50

Hopefully the spacing looks great, with regards to the button Face and Rim, just like the example below:

Image 51

Now this is fine for a 100x100 pixel button like ours. But I wonder what would happen if I changed the button size to 32x32 pixels. (Which is probably the lowest resolution worth displaying a stylised button in).

But rather than change the size of this button, I'm going to create copies of this Button Style. These copies will update dynamically, because they share the same Style and Template. So come out of the Button Template and Style using the Return Scope icon. Place two more buttons on the page, directly below the first. Set the sizes to 64x64 and 32x32 pixels, respectively.

Image 52

We now need to tell the new buttons to use our Style, that we named ButtonRound1.

Right click on the middle button and select Edit Template > Apply Resource > "ButtonRound1".

Image 53

Another way would be to go to the Resources tab, and inside [UserControl], select "ButtonRound1".

Image 54

Drag this Style Resource onto your button, release the mouse, and select Style from the small popup window.

Image 55

Things are not looking good for the two 2 smaller buttons, but fine on the largest. What is going wrong?

ExpressionBlendButtons/imgC1.jpg

The Face of the button is not spacing correctly within the Rim, because of the Margins we set on the Face. Go back in to the Button Template and select the Grid named Face. Change the Margins to 4 and review the results.

Image 57

See how the Face now fits correctly in the smallest button, but not in the biggest one. Setting a Margin is definitive, and sets a fixed distance in pixels from its reference object (parent).

So Margins do not really work, as the Rim and Face do not reference each other, they both reference their parent.

Section 3 - Scalability Issues

Earlier, I said there are two ways to size your objects within Expression Blend, but there are a few more! All are used in conjunction with Auto Size, with Horizontal and Vertical Alignments set to Stretch (the defaults). (So the child elements will Stretch to respond to the instructions of the parent object.)

So to properly reference the Face and the Rim from each other, we will use a Scale Transform. Select the Grid named Face and Reset the Margins to 0.

Just below the Margins in the Properties tab is a section called Transform; open this section if currently collapsed and select the Scale tab.

Image 58

Now set the Scale for the X and Y axes to 0.8. The Face is now sitting nicely within the Rim at all three sizes.

Image 59

You have probably noticed that we still have the black border on the Face, called the Stroke. It almost seems to get heavier and thicker as the button gets smaller. It doesn't, as it is exactly 1 pixel thick on all three buttons. But 1 pixel is a larger proportion of the button surface in the smallest button than it is in the biggest.

Select the Ellipse named BGround1 in Objects and Timeline. Change the Stroke Thickness in the Appearance section of the Properties tab.

Image 60

Give it a value of 4 and review your results.

Image 61

The Stroke does not scale and as such should be avoided most of the time, so let's get rid of it. We could set the Stroke Thickness to 0, but it's better to tell the Ellipse to have No Stroke.

So firstly, Reset the Stroke Thickness to 1, as this keeps things tidy and the XAML cleaner. And with the Stroke selected in the Brushes section of the Properties tab, select No Brush.

Image 62

Let's get the ContentPresenter out of our way as well, as it is just a distraction for the moment. To hide it at design time, go to Objects and Timeline and click the "Eye" icon next to the element. It will be visible at run time, which is OK, and not really what I want, so instead I will hide it at run time.

To do this, select the ContentPresenter and in the Properties tab, change its Visibility to Collapsed.

Image 63

Now let's start adding some depth to our button Face by adding another Ellipse that sits over the top of BGround1. Select the Grid named Face and double click the Ellipse icon in the left tool bar.

Image 64

This will insert another Ellipse with nice clean "Default" settings inside of the Grid element named Face. Select the Ellipse and rename it "FaceRadialGradient". And for clarity, while we are at it, let's rename the Ellipse named "BGround1" to "FaceBGround".

Image 65

(Stay on top of naming your elements to prevent confusion and to help others reference them later.)

Now with the element FaceRadialGradient selected, remove the Stroke and set the Fill to Gradient (Radial).

Image 66

If your Gradient Stops are set as default, the Face will look like mine below:

Image 67

Now flip the Gradient Stops using the "Reverse Gradient Stops" icon to the right of the Radial Gradient icon.

Image 68

Your button Face should now look like this:

Image 69

Now select the left Gradient Stop, set the Alpha to 30%, and move to 75 on the Ribbon.

Image 70

Now select the right Gradient Stop and set the Alpha to 50%.

Hopefully your button is starting to look better.

ExpressionBlendButtons/img25a.jpg

Now why did I bother to reverse the Gradient Stops earlier? (So Black was on the Right and White was on the Left.) Because the Tone as well as the Transparency (Alpha) has an effect on the Gradient of the Fill (colour can be used in the Tone, but this will reduce flexibility when changing colour schemes).

With the right Gradient Stop at 100 on the Ribbon selected, change the colour from Black to White. Review the results:

Image 72

With the Gradient Stop set to black, the edge of the Face is looking fairly dark. And we could adjust the Tone of the right Gradient Stop to a dark grey. But I also want to change the way the light hits our button. So we will access some seemingly hidden controls for the Gradient Brush. In the left hand tool bar, select the Gradient Tool. (Hopefully, you will now have an Arrow tool over the top of the button face.)

Image 73

If you can't see the Gradient Tool, look in the Projection section of the Properties tab.

Make sure it is set to "Default" for your element and all its parent elements.

(Blend is unable to show the Gradient Tool when a Projection is set on an element, or on any of its parent elements).

There are a number of things we can do with the Gradient Tool, like adjusting the Gradient Stops.

But we are more interested in other options, like offsetting the centre and adjusting the size.

So click and drag on the stem of the Arrow (Not near the Gradient Stops) and move upwards towards the left a little.

Image 74

Now click on the head of the Arrow to enlarge the scope of the gradient.

So that it just covers the lower right edge of the Face.

Image 75.

The Face now looks like it has the light source in the top left corner. at about 315% (360%-45%).

(Or 180% opposite to that, if you view that button as concave, rather than convex).

Things are starting to look nicer, but I'm still not happy about the spacing between the Rim and the Face.

It is OK in the largest button, but lost and almost non existent in the smallest.

It is proportionally correct, but not really what we want.

Ideally we want the Rim spacing not to Scale when we resize.

Or to be limited in some way, which we can do using Margins.

So select the Face element in the Objects and Timelines, and set a Margin of 1 on all sides.

The button Face has reduced in size by 1 pixel on all sides, for all 3 of the buttons.

Image 76

Which has helped and has had very little affect on the largest button.

As 1 pixel is only 1% on a button 100x100 pixels.

But 1 pixel is about 3% on the 32x32 pixel button.

So we have combined 2 methods of controlling the size and relationship of the Face and the Rim to their parent.

A Scale Transform and a Margin.

(One proportional to the scale of the object and another that is finite).

Now that the spacing is better, the Rim needs to be a bit fatter.

So with the Face element still selected, change the Scale Transform to 0.75 for both the X and Y axis.

Now select the Rim element and edit the Opacity Mask in the Properties tab.

Change the Gradient Stops we set earlier, from 0, 84, 85, to new locations on the Ribbon at 0, 79, 80.

The Rim should now have more of the inner visible.

Image 77

We now need to update the gradient overlay for the Rim, to span across the larger band we revealed.

So select the Ellipse named "RadialGradient" and while we are here, rename it "RimRadialGradient".

Then do the same for the Ellipse named "BGround", renaming it "RimBGround".

(This is neater and will be easier to reference later.)

Select the RimRadialGradient element again.

And change the Gradient Stops of the Fill, in the Properties tab to: 80, 87.5, 92.5 and 100.

Image 78

We now have a better proportioned button, with a fatter Rim.

Image 79

If you are wondering if we still need the Margins to control the spacing of the Rim to the Face.

Try resetting the Margins of the Face element to 0.

If anything, a value of 2 could be better, so set the Margins to that.

We will also get rid of the horrid red background.

Image 80

It makes sense when designing, to ensure your UserControl (Button) looks good on dark background, as well as a light background.

So come out of the Button Template, using the Return Scope icon.

Select all 3 buttons, and use Copy and Paste to duplicate 3 more, and moved them to the right.

Then place a Rectangle with a black fill, higher up the tree in the Objects and Timelines and therefore behind the buttons.

(You are now fully in control, of how my button will look, in almost any situation!)

Section 4 - Cosmetic Surgery

Time to make things pretty, now we have the bare bones of our button.

I want to apply a gradient on the Rim, to mimic the lighting effect on the Face.

Go back into your Button Template and select the RimRadialGradient element.

In the Properties tab, select Opacity Mask and set a Linear gradient.

Select the Gradient Tool in the left hand toolbar and set as shown below:

Image 81

Set a Gradient Stop to 15 on the Ribbon and the Alpha of 50%.

Then set a Gradient Stop to 85 on the Ribbon and leave the Alpha at 100%.

(Tone and colour is not relevant in an Opacity Mask, as only Transparency is being affected).

Set the head and tail of the Gradient Tool to the corners of the bounding box to ensure a 45% angle.

But there is no point having the Gradient Stops at 0 and 100 on the Ribbon.

(We can only apply the Opacity Mask to what is visible in the element).

Image 82

So the top left of our Rim, looks a little bit brighter than the bottom left.

But more contrast is required and it is not only the Opacity Mask that is determining how visible this element is.

Set the Opacity for the element in the Appearance section to 50%.

Image 83

But this only reduces the visibility and contrast of this element.

(Or layer - If you are thinking Photoshop!)

Instead look at the Fill of the element, to see what we previously set.

Image 84

The Gradient Stops at 87.5 and 92.5 on the Ribbon, have an Alpha of 60%.

Change the Alpha for both of these to 90%.

Image 85

Which helps, but we need to Reset the Opacity of this element back to 100%.

Which hopefully should give something looking like this:

Image 86

Now there is plenty of contrast applied to our diagonal gradient Opacity Mask.

But we had to increase the contrast of the Fill, to increase the contrast of the Opacity Mask.

The Fill and Stroke of an element, are the primary components, when it comes to the transparency of that element.

If the Fill has an Alpha of 50% and the Opacity of that element is only 50%, then I will effectively only see 25% of that element.

Even if I set the Opacity of that element to 100%, I can still only see 50% of it, as that is controlled deeper, in the Alpha value of the Fill.

You might now be asking.

Why set the Alpha values to 90% and not 100% and then set the overall Opacity of that element to 90%.

Will this give me the same results? In this example, almost none, but there is a difference!

Image 87

With the Gradient Stops set to 90%, rather than 100%, I have slightly more influence over the Tone.

Also I believe 90% is the maximum value, I would ever want applied to this element.

So this way, I am prevented from exceeding this value, by setting the Opacity above 90%.

Now our button Rim is looking very shiny, and that might be enough for your purposes.

But it is not very realistic...

What it really needs, is for the Rim to catch the light:

Only on the outer edge, in the top left corner.

And only on the inner edge, in the bottom right corner.

Something like the image below:

Image 88

So how do we go about creating a more realistic light effect for a raised Rim?

Firstly, Reset (remove) the Opacity Mask applied to the element RimRadialGradient, as this is no longer needed.

This gives us an very bright looking Rim, so set the Opacity of RimRadialGradient to 40%.

Image 89

This element (layer), will now provide just the basic contour/outline of the Rim.

We will overlay 2 more Ellipses to define our highlights.

Select the Rim element and using the using the Ellipse tool in the left hand tool bar.

Insert 2 new Ellipses in the Grid named Rim, and remove the Stroke on both Ellipses.

Rename them "RimHighLightUpper" and "RimHighLightLower" respectively.

Image 90

Click the "Eye" symbol next to the RimHighLightUpper element to hide it.

Now we can work on RimHighLightLower, without RimHighLightUpper getting in the way.

Select RimHighLightLower and set a Radial Gradient Fill, with white Gradient Stops at 86, 94 and 100 along the Ribbon.

Set the Alpha to 0% for all the Gradient Stops, except for the one at 94, which should be 100% Alpha.

Image 91

Using the Gradient Tool, move and resize the gradient to look like this:

Image 92

The gradient looks good on the bottom right inner edge.

But there is an unwanted highlight, on the inner edge at the top left.

So to get rid of this, let's apply an Opacity Mask, that only shows the part we want.

So set a Linear Gradient in the Opacity Mask as shown.

Image 93

With Gradient Stops at 55 and 75 on the Ribbon and set the Alpha of each to 0% and 100% respectively.

Image 94

That looks OK for the lower highlight, so hide this element and move on to the upper highlight.

Select the RimHighLightUpper element and unhide it.

With the RimHighLightUpper element selected, set the Fill to a Radial Gradient.

Now set white Gradient Stops of the Fill to 86, 92 and 100 along the Ribbon.

Set the Alpha to 0% for all the Gradient Stops, except the one at 94, which should be 100% Alpha.

Next apply an Opacity Mask, with a Linear Gradient, just as we did for the lower highlight.

With the Gradient Stops at 55 and 75 and the Alpha of each to 0% and 100% respectively.

(The only difference is, we are pointing the Gradient Tool head and tail in opposite directions).

Now select the Fill again, and with the Gradient Tool selected.

Offset and enlarge the gradient to look like the image below:

Image 95

With that done, unhide the element named "RimHighLightLower", and admire the efforts of your work!

The highlights are maybe a bit strong and need a bit of adjustment.

So set the element Opacity of RimHighLightLower to 70%, and 80% for RimHighLightUpper.

Image 96

Which I think concludes all we need to do for the Rim of this button.

So let's go back to the Face and see what we can do there.

Select the FaceRadialGradient element, and in the Fill properties.

Change the Gradient Stops of the Radial Gradient to 40 and 100 on the Ribbon.

Set the Alpha values to 100% and 0% respectively, and position using the Gradient Tool as shown.

Image 97

Now set an Opacity Mask with a Radial Gradient and Gradient Stops at 79 and 80 on the Ribbon.

Set the Alpha values to 0% and 100% respectively.

Hopefully your Artboard looks something like this:

Image 98

Now the button is starting to really take shape, we have a nice looking Rim.

And the Face has an attractive border and Inner ready for us to get creative with.

So far, we have used Opacity Masks extensively to limit what is being shown in an element (Or layer).

But it makes no sense here to use an Opacity Mask to limit what is being shown.

As we would need to keep applying more Opacity Masks to my elements.

Just to preserve the Transparency and hence the background colour of the button.

But we don't need to worry about Transparency, as we are only showing the background colour.

And this is a Resource, that is set in the Style of the button (UserControl).

So remove the Opacity Mask applied to FaceRadialGradient.

Instead create a new Ellipse in the Face element, name it "InnerBGround".

Image 99

Right click on the InnerBGround element and select Group Into > Grid.

Rename this Grid to "Inner" and ensure it is expanded to show its child elements.

Now change the Scale in the Transform section of the Properties tab to 0.8 for the X and Y axis.

Select the InnerBGround element and remove the Stroke.

Now select the Fill property and in the Advanced Properties Option button, select Template binding > Background.

Image 100

Now we have the same result as applying an Opacity Mask, to form the Inner of our button Face.

But with the freedom to start overlaying effects from the start, or using the Stroke.

As well as re-adjusting or tweaking our layout, with regards its spacing at different sizes.

So select the Grid named "Inner" and set Margins 2 on all sides.

This helps enlarge the border of the Face for the smallest sized button, just like we did for the Rim.

Now add 2 more Ellipses in the element named Inner.

Rename these "InnerEdgeShadow" and "InnerGlossHighLight", remove the Stroke on both elements.

Image 101

Now hide the InnerGlossHighLight element and select "InnerEdgeShadow".

Change the Fill to a Radial Gradient, with black Gradient Stops at 50 and 100 on the Ribbon.

Set the Alpha values to 0% and 100% respectively.

Image 102

Now change the Opacity of the element (or layer) to 30%.

Image 103

Now unhide the element named "InnerGlossHighLight" and select it.

Give it a Fill of Radial Gradient and white Gradient Stops at 49 and 50 on the Ribbon.

Set the Alpha values to 100% and 0% respectively.

Image 104

With the Gradient Tool selected, change the proportions of the gradient to match shown.

Image 105

(You could set the Gradient Stops anywhere on the Ribbon and resize the Gradient Tool to suit.)

Now change the Opacity of the InnerGlossHighLight element to 50%.

Then apply an Opacity Mask, with a Linear Gradient at Stops at 0 and 50 on the Ribbon.

Set the Alpha values at 100% and 0% respectively.

Image 106

Using the Gradient Tool, ensure the gradient looks like the image below:

Image 107

Now we have pretty much recreated Timmy Kokke's Glass Orb Button.

The only real difference, is that I have not subdivided any Grids to control the proportions.

(Both methods are equally effective, it just depends on what you prefer and the circumstances, to define the best approach!)

Now let us rotate the InnerGlossHighLight element with a Transform, to give it the same highlight Angle as the Rim.

Select InnerGlossHighLight and in the Transform section of the Properties tab, change the Rotation Angle to 45%.

Image 108

(So what happened? The gloss highlight has disappeared.)

The problem is the Opacity Mask, which will only work correctly at Angles 0 and 180.

But to get around this, we will Reset the Rotation Angle back to 0 and instead apply a Projection.

So in the Projection section, (directly below) set the Z Rotation Angle to 45%.

Image 109

Your buttons should now look like this:

Image 110

Remember that I spoke earlier about the Gradient Tool not being visible on an element, when a Projection is being applied?

So select the element named "InnerGlossHighLight" and try editing the Fill or Opacity Mask with the Gradient Tool.

The Gradient Tool is not accessible, or at least not in Blend 3, but who knows for future releases.

So just to prove my point, remove the Projection and see that the Gradient Tool is now visible.

Image 111

Now there is just one more thing to change on this button, so with the Projection re-applied.

Select the RimHighLightLower element and change the Opacity to 50%.

Now that should have reduced the highlight on the rim on the lower right hand side.

Image 112

Feel free to get creative, and modify this button, but I'm happy with the look of it now.

Section 5 - Interaction and Animation

Now we have an attractive button, it is time to breathe life into it, by adding some Interaction and Animation.

But firstly, we need to have something to animate, and we will start by adding a spot of colour.

Now because we have created the button with 3 basic components, a Rim, a Face and an Inner, we can easily introduce an overlay to affect the colour of each of these components, so let's start with the inner.

Ensure you are in the Button Template and have the Grid element named "Inner" selected.

Now insert a new Ellipse and name it "InnerOverlayColour".

Move it in the list of the Objects and Timeline to the position shown in the image.

Image 113

Remove the Stroke of the InnerOverlayColour element and set the Fill to bright red.

Image 114

Now this looks a little bright and unrefined, so let us use an Opacity Mask (which appears to be my favourite tool!).

So set an Opacity Mask with a Radial Gradient and Gradient Stops at 25 and 100 on the Ribbon.

Set with Alpha values to 100% and 50% respectively.

Image 115

That is better, but still a little bright, so set the Opacity to 90% for the InnerOverlayColour element.

Image 116

Now we have a nice warm central glow, fading out to black at the edge.

This a combination of the Opacity Mask and the InnerEdgeShadow element.

Try changing the Opacity of InnerEdgeShadow to 10% and the Fill of InnerOverlayColour to Green.

Image 117

When you are happy, reset the Opacity of InnerEdgeShadow to 30%.

To help you develop a nice colour scheme, set the Fill of InnerOverlayColour to Template Binding > BorderBrush.

Image 118

Now go to the Style of your button, by clicking on the icon, at the top left corner of the Artboard.

Image 119

Ensure the Style is selected in the Objects and Timelines.

Image 120

Now change the Background and BorderBrush colours of your Style.

See how easy it is to edit the whole colour scheme of the button.

Image 121

I'm going to use RGB values of 60, 50 and 0 for the Background and bright red for the BorderBrush.

Image 122

You may see the Style has another colour brush, named "Foreground" that we could Template Bind to.

And you might be wondering why we didn't use this one, rather than the BorderBrush.

Well the Foreground brush controls the colour of the ContentPresenter, which is currently hidden.

And making the centre of the button, the same colour as the ContentPresenter would mean one is not visible over the other.

So let us just leave things as they are.

Image 123

We now need to decide, what will our button do?

During the various mouse states and how do we set these states?

Ensure you have the States manager tab open, in the top left area of the window.

Image 124

You should see a list of CommonStates, consisting of Normal, MouseOver, Pressed and Disabled.

Above the CommonStates is the Base state and this state is applied as the default for all other states.

Image 125

So let us set the Base state, to have NO red glow.

And as long as we have no Keyframes set, what we define here, will be reflected in all the other states.

This means that the Normal state, does not normally require any Keyframes.

As it is generally the same as the Base state.

So ensuring you are in the Base state, select the InnerOverlayColour element and set the Opacity to 0%.

Image 126

Now select the MouseOver state and set the Opacity of the InnerOverlayColour element to 50%.

Image 127

Then select the Pressed state and set the Opacity of the InnerOverlayColour element to 90%.

Image 128

Now run your application by pressing F5.

Hopefully, your button glows in the middle during MouseOver, getting brighter when Pressed.

But it needs some refinement, as the transition from state to state is happening instantly.

It needs slowing down a bit, over a defined duration of time.

So set the Default Transition duration to 0.1 seconds.

Image 129

Run your application and see the change.

(As the transition from state to state is so simple, only a very short duration is required).

(Setting too long a duration, makes the transition seem to lag).

What can we do next? Well, we could do a simple colour change to say green, when the button is Pressed.

But that would not be very smart, as about 10% of the population are red and green colour blind.

So let us introduce some motion instead and make the button Face grow during MouseOver and Pressed.

Select the Face element and with MouseOver state selected.

Change the Scale Transform to 0.82 for both the X and Y axis.

Image 130

Select the Pressed state and do the same as you did for the MouseOver state.

Now run your application (F5).

Because we now have motion during the Transition, from Normal to MouseOver.

The Opacity we initially set for that Transition seems a bit excessive.

So ensuring you are in the MouseOver state, select the InnerOverlayColour element and set the Opacity to 30%.

Now check your results and while you are there, look at the MouseOver state on the smaller buttons.

The Face does not grow to touch the edge of the Rim, as it does in the largest button.

This is because of Margins we set on the Face element.

We can change the Margins for different states, but they will not animate.

They will be applied at the end of the Transudation duration, in one block, resulting in a jolty animation.

So we will not be setting up different Margins for various states, as this will only give problems.

But we can make the Margins work better, by tweaking them a little.

Change from the MouseOver state to the Base state.

And set the Margins of the Face element to 1 on all sides.

Run your application and see that the smaller buttons are functioning better now.

Now let us now add a bit of "pop" to our transition, by applying an Easing Function.

First, change the Transition duration to 02. seconds, then click on the small square to the left and select the EasingFunction "Back Out".

Image 131

This will change the manner in how the Face will Scale, over a new duration of 0.2 seconds.

I have increased the duration, so that the Easing Function has more time to animate.

You may prefer to set the duration to 0.3 seconds, your choice!

Run the application, and test your button at various sizes.

The Face should "pop" as it changes Scale, and this will be applied to all the Keyframe changes.

Now it is probably not normal, for someone to press a button, and to hold it Pressed.

But for demonstration, we will.

So let us set an animation, to loop during the Pressed state.

Select the Pressed state and the InnerOverlayColour element.

Now open the Timeline by clicking the Show Timeline icon.

Image 132

Now in the Timeline, set a Keyframe at a duration 1.6 seconds, as shown in the image below.

(Use the Record Keyframe icon, or just make the change in the Properties tab to automatically generate one.)

Image 133

Now move the Timeline to 0.8 seconds and insert another Keyframe.

Now change the Opacity of the InnerOverlayColour element to 50% for this Keyframe.

(We set the last Keyframe first, so that it copied the values from the Keyframe at duration 0 second.)

(This way our animation can loop, as the start and the end are the same.)

Now select the Pressed timeline in the Objects and Timeline, as shown in the image below:

Image 134

In the Properties tab, select the RepeatBehaviour and set to "Forever".

Image 135

Run your application, press and hold your button, and hopefully admire your glow and fade animation.

Now your glow and fade animation is changing in a linear manner, when it should be more like a sine curve.

We can set an EasingFunction for each individual Keyframe to mimic this.

Simply by clicking on each and setting the EasingFunction in the Properties tab.

I will leave mine as they are, but feel free to play.

(I'm more interested in making the red glow, grow and shrink as it fades in and out.)

Which we could try and achieve by applying a Scale Transform.

But I already know this will not work very well.

As the edge transparency (Alpha) of the InnerOverlayColour element, is only set to 50% in the Opacity Mask.

This means it will have a hard edge when I try to shrink and grow the element. Not very desirable.

As I mentioned earlier, the InnerEdgeShadow element also controls the edge glow of the inner and it is this we will change.

So in the Pressed state, select the InnerEdgeShadow element and set an animation, for a duration of 1.6 seconds.

(Just as we did for the InnerOverlayColour element.)

Image 136

Now at 0.8 seconds, set the Opacity of the InnerEdgeShadow element to 60%.

And the Opacity of the InnerOverlayColour element to 70%.

Run the application and test the results.

Image 137

We now have a brighter central core and a darker edge to the inner glow.

Resulting in a more realistic electric light bulb glow and fade.

We can further emphasise this, by animating the Gradient Stops on the Fill of the InnerOverlayColour element over time.

So still in the Pressed state and at a duration of 0.8 seconds.

Change the Gradient Stop set at 50 on the Ribbon, to 30 on the Ribbon.

Image 138

Test the application, and hopefully your button dims to a central core in the Pressed state

(This hopefully may inspire you to create a Cyborg, or maybe Kit from Night Rider!)

Now let us animate some other parts of our button, like the Rim.

So select the Base state, in the States manager.

Select the Rim element and insert an Ellipse within this element and rename it "RimOverlayColour".

Remove the Stroke, set the Fill to Template Binding > BorderBrush.

In the Objects and Timeline, position the RimOverlayColour element, in front of the RimBGround as shown.

Image 139

Ensure the Opacity of the RimOverlayColour element, is set to 0% in the Base state.

Now in the MouseOver state, set the Opacity to 20% and to 40% for the Pressed state.

In the Pressed state, set an animation for a duration of 1.6 seconds, just like we have before.

Now at 0.8 seconds on the Timeline, set the Opacity of the RimOverlayColour element to 0%.

Run your application.

Hopefully you will have a slight red hint on the Rim during MouseOver and a stronger glow and fade during Pressed.

Now at the risk of going overboard, let us Scale the Rim to pulse in size, during the Pressed state.

In the Pressed state, select the Rim element and set up an animation just as we have before for 1.6 seconds.

Now go to the Keyframe at 0.8 seconds and set a Scale Transform for the Rim element, by changing both the X and Y axis vales to 1.05.

Run your application and see how the Rim now seems to breathe, even if it may be a little over the top!

(I will leave you to fine tune the animation with the EasingFunction, for each Keyframe).

This is just an exercise and why I committed, what could be considered a cardinal sin!

By increasing the Scale of the Rim to more than 1.

As the Rim will now sit outside of its boundaries when Pressed and may overlap with other objects on the page.

But as I only increased the Rim Scale a tiny amount, from 1 to 1.05, I think it would be OK and could leave it.

Or in the Base state, resize the 3 main parts of my button (the Rim, the Face and its Inner).

As well as All the Scale animation Keyframes we have set.

But a quick and dirty way to compensate, is to Scale the parent object of all 3 parts of the button.

So select the element named "[Grid]" in the Objects and Timelines.

(I have collapsed the tree for clarity in my image).

Image 140

Now set a Scale Transform for both the X and Y axis of 0.95.

(This will compensate for the 1.05 Scale of the child object).

You can leave this correction if you like, but I'm going to remove it.

As I am certain that this UserControl, will always have more space (Padding) around it, than our animation will encroach.

Now we have one last change to make for the 3 main States of the button.

So select the RimHighLightLower element and in the MouseOver and Pressed state, set the Opacity to 30%.

This gives a slight hint that when the button Face grows in size.

It blocks some of the light from hitting the inner lower edge of the Rim.

That is all I will do with regards to animating this button.

But please feel free to enhance it further, by maybe animating the border area of the Face.

Section 6 - Multiple Colours and Final Touches

Image 141

During the previous section on animating our button, we only applied one colour state to our button.

Now there is nothing to stop you animating the Fill of an Ellipse.

And therefore, changing the colour of a button for different state.

This is unless: The colour you are using is Data Bound.

And in this case, Template Bound to the BorderBrush in the Style of our UserControl (Button).

We cannot change this Style Resource over time, as it is outside of our control and would make no sense to do so anyway.

(It would change the colour of every object, item and element, that references this Resource, probably the whole page/application!)

Instead, we will add more Ellipses to our UserControl (Button).

So ensure you are in the Button Template and in the Base state.

Select the Grid element named "Inner", insert and position a new Ellipse named "InnerOverlaySecondColour" as shown.

Image 142

Remove the Stroke, set the Fill to bright purple (RGB 255, 0, 255) and the Opacity of the element to 90%.

Image 143

Now set an Opacity Mask, just like you did for the Template Bound element InnerOverlayColour.

So select InnerOverlayColour and select the Opacity Mask.

Now click on the Advanced Properties button and select "Convert to New Resource".

Image 144

In the Popup window, name your Brush Resource "ColourMask" and press OK.

Image 145

Now go back to the InnerOverlaySecondColour element and select the Opacity Mask.

Click on the "Brush Resources" tab and select "ColourMask" from the Local Brush Resources.

Image 146

Now the bright purple is toned down, let's animate the Fill of this element.

Select the MouseOver state and change the Fill to bright green.

Image 147

Now we want to remove the Scale Transform we applied earlier.

To the Face element, during the MouseOver state.

So still in the MouseOver state, select the "RenderTransform" applied to the Face element in the Objects and Timeline and hit delete.

Image 148

The button now shrinks to Scale values of 0.75, for both the X and Y axis.

These are the values set in the Base state and hence the default for our button.

(But resetting the values of the Scale Transform in the Properties tab, would yield different results, the scale would reset to 1.0, not what we want!)

(Expanding the tree to reveal all operations applied to an element, this can reveal any unwanted, or unneeded animation Keyframes)

Now that the button is smaller compared to the Rim, in the MouseOver state.

We should also reinstate the lower inner highlight on the Rim, back to the Base state.

So repeat the process to remove an element Keyframe, (this time, it is the Opacity you need to delete).

Image 149

And once again for the Opacity of the InnerOverlayColour element.

Image 150

Next, ensure you have the InnerOverlaySecondColour element selected.

Go to the Pressed state and set the Opacity to 0%.

Run your application and review that result.

Hopefully, your button changes from purple, to green, to red.

Notice how when the colour changes, it seems to blink in the middle, let us investigate.

Set the Default transition to 2.0 seconds and run the application again.

Image 151

Hopefully you can see that as the Opacity of one colour decreases, the Opacity of the other increases.

This leaves a dead spot in the middle of the animation, that is not filled by the changing colours.

I am not unhappy with this effect, as long as the timing is adjusted correctly.

(There are ways to modify this behaviour, but don't want to get carried away here.)

Look at the EasingFunction of the Default transition.

Which we set as "Back Out", to give a "pop" action to our Scale Transform.

Image 152

Look at the profile of the curve, to see how it affects the animation.

From a starting point of zero, the curve ramps up steeply, peaking well above 100% and settles back down to 100%.

We can change how emphasised the peak is beyond 100%, by changing the Amplitude.

Also, this EasingFunction profile reaches 100%, in almost the first quarter of the duration.

It is not helping with the colour change and us setting a suitable duration.

So remove the EasingFunction and set the Default transition to 0.5 seconds.

Image 153

Run the application again, notice how the duration of the colour change is about the same.

(One quarter of the time, without the EasingFunction that reaches 100% in roughly one quarter of its profile).

Now change the Default transition to 0.3 seconds, as I think that is about right.

Next, we will adjust the MouseOver state, to better suit our evolving button.

Select the Rim element and set a Scale Transform in both the X and Y axis of 1.05.

Now run your application and see what you think.

(I spoke earlier about colour blindness, so I have ensured a clear geometric change between MouseOver (Green) and Pressed (Red).)

Now there are lot more things we can animate, but I will leave these to you, but here are some suggestions:

  1. Set lowlights on the opposite edges of the Rim to the highlights.
  2. Animate the lower highlight Opacity in the Pressed state, to match the Rim grow and shrink.
  3. You could also set the border area of the Face, to glow red in the Pressed state to match the Rim glow.

Essentially do anything you like, use your creativity, there is no right or wrong, just personal taste.

Have a look at different EasingFunctions, play with the state to state transitions as well.

Section 7 - Focused, Disabled and Content

If you are coming from a graphical background.

You have probably never had to produce artwork, taking things like Focused into account.

Focused is a graphical way to indicate to the user, what Control on the screen is currently selected, or has the focus of the Tab control.

The Focused state could be decorate, but this is not recommended.

As it should be common and uniform to all your Controls and its primary role is an aid, not a toy.

(But that is my opinion and as I have no intention of designing a focused style for all the controls I might need).

Ensuring you are in the Base state, select the element named Grid and insert a new Ellipse named "FocusVisualElement".

Image 154

Remove the Fill and with the Stroke Thickness set to 1, change the colour to (RGB 109, 189 and 209).

Image 155

Now in the Base state, select the Opacity and set it to 0%.

Then select the Focused state and set the Opacity to 100%.

Now select the Base state again and click on the eye icon to the left of the Focused state.

Image 156

This allows us to work in the Base state and not set any Keyframes that define a change from the Base state.

But most importantly, see the Focused state and elements, that are invisible in the Base state.

Now run your application, select the button to give it Focus and test the Normal, MouseOver and Pressed states.

You should hopefully have a blue ring around the edge of your button, but like mine, does not animate with the rest of my button.

So move the FocusVisualElement element, to inside the Grid element named Rim.

Image 157

Now run your application, and see that the Focus now follows the animation applied to the Rim.

But it is not as clear as it could be (in my opinion), as it is placed over the top of the outer edge of the Rim.

(In a default button, the Stroke ring is just inside the edge of the button, but here I will set it outside.)

So with the FocusVisualElement element selected and in the Base state, set the Margins to -1 on all sides.

This helps give the Focus a bit of clearance, just in case the colour scheme matches the Focus colour.

Run the application to review the results.

Image 158

You might be thinking that we could put the Focus, between the Rim and the Face of the button.

But we have set an Opacity Mask to the Rim, so if we want the Focus to be visible in this area, we need to do some work.

As I see it, we have 3 immediate options, but I will leave you to ponder these.

I am happy with the Focus as it is, so I will move on.

Disabled

We also need to define a state for Disabled, which generally partially blanks out all the parts of the Control.

And as there are 2 parts to our button, we need 2 elements to blank it out.

As we don't want to influence the transparent part of our Control.

Start with the Rim and in the Base state, place a new Ellipse in the element named Rim.

Rename this new Ellipse "DisabledVisualElement", remove the Stroke and ensure the Fill is white.

Image 159

Now set the Opacity to 0% in the Base state and to 55% in the Disabled state.

(55% is the setting used in a default Button.)

Now back in the Base state, insert a new Ellipse in the element named Face.

Rename it "FaceDisabledVisualElement" and position as shown.

Image 160

In the Base state, set the Opacity to 0% and in the Disabled state to 55%.

Hopefully, your button should look like this in the Disabled state.

Image 161

Content

Because of the visual style of this button, it is un-likely we would want any content in the button.

Be it an Image, an Icon, or a ContentPresenter.

But we should make some provision for the ContentPresenter, in case it is needed.

Select the ContentPresenter element and in the Base state, change the Visibility from Collapsed to Visible.

Image 162

Now hopefully your buttons will look like this:

Image 163

Run the application and see that the Scale of the ContentPresenter does not follow the Scale of the button Face.

This may be Ok for you, but I would like it to track the Scale of the button Face.

So move the ContentPresenter inside the element named Face.

Image 164

The text is now smaller, as shown in the image below, but will grow along with the Face.

Image 165

The animation change is hardly noticeable in the running application, as the text is too small and difficult to visually reference.

It is not realistic to presume the text will work in the smallest button, so making the text smaller to fit, would just be stupid!

And we don't really want to try and Scale the text, to fit at all possible button sizes.

We also need to remember that by placing the ContentPresenter in the Face.

The Scale of the text is being reduced by 0.75 or 75%, of the size defined by the Style.

So should be edit the Font Size in the Style?

Or should we change the Scale of the ContentPresenter in the Button Template?

We should change the Scale of the ContentPresenter in the Button Template and not the Font Size in the Style.

This is because, when we apply this Style to objects on your page, the Font Size will match in Scale to other objects on the page.

(If we set a Font Size of 11 in the button Style and did the same for a textbox Style, we would want them the same size on the page, not 75% of that)

So let us compensate for the Scale Transform, that we automatically applied of 0.75.

When we placed the ContentPresenter in the element named Face.

Select the ContentPresenter and while in the Base state, set a Scale Transform for both the X and Y axis of 1.25.

This will bring the Font Size back inline with the default settings of the button Style and comparable with the Styles of other Controls.

Now go to the Style, by clicking on the Style icon at the top left of the Artboard.

Image 166

Ensure your the Font Size is Reset to the default of 8.25.

Image 167

Hopefully, the text on your buttons will be the same scale as mine.

Image 168

Which look fine in Expression Blend, but the Text is still very small when run in a web browser.

Image 169

So it is fair to say, that in this UserControl (Button).

Where text is overlaid on a graphical component, it needs to be bigger to make it clear.

Now we could again increase the Scale of the ContentPresenter, but not this time.

Instead, we should increase the Font Size in the Style.

So that it is preset within the Style, as the recommended minimum for this UserControl.

When we apply this Style to any button, the Font Size will change to our preset (unless we override it) and suitably adjusted for this UserControl.

So change the Font Size to 11 in the Style, run the application and decide for yourself.

Image 170

Now a text string (or word), is not really suitable for the smaller button sizes.

So come out of the Style for the button by clicking on the "Button" icon (Or Return Scope icon).

Image 171

Select the smallest button and in the Common Properties of the Properties tab, Reset the Content.

Image 172

(Notice that the default Font Size is 11 and this is because it is set in the underlying Style)

Next select the medium sized button, change the Content to "8" and the Font Size to 24.

Image 173

Then do the same for the buttons on the dark background.

Now hopefully your buttons look like this, when displayed in a web browser.

Image 174

And that I think is the end!

Here is the source code for the completed button with the three recommended updates.

Even though, I would rather you built it yourself!

Summary

I hope you found this tutorial educational, as I have attempted to keep it as linear and un-repetitive as possible.

But at the same time, learning from our mistakes, adjusting as we need, to get the best from our layout capabilities.

Really what I want, is for your creativity to take over and to take the path I have shown.

I'm not saying it is the only path, so post a tutorial yourself, if you can add constructively.

Let me know if you would like more tutorials, for some of the other button Styles shown in the Introduction.

Other Tutorials

And one last thing, please please please rate my articles! :-)

History

  • 11th March, 2010: Initial version

License

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