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

Building Better Buttons in Expression Blend and Silverlight

, 3 Apr 2010
Rate this:
Please Sign up or sign in to vote.
A beginner's guide to building 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!

IntroA..jpg

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 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.

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.

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".

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.

(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.

(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 complied 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.

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.

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.

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.

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.

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.

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.

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:

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

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

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.

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

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 to the Padding property of the Style.

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.

(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.

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

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.

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

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.

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.

(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.

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.

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.

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

Now select the Ellipse and duplicate the Ellipse by using the keys "Ctrl +C", "Ctrl +V" (Copy & 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.

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

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.

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

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".

Next, change the gradient from Linear to Radial.

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

(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:

Not very pretty yet, but you can see 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".

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%:

Or by adjusting the Opacity of the whole element.

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.

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.

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.

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.

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".

(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.

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

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.

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

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.

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".

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

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

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

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.

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.

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.

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.

Give it a value of 4 and review your results.

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.

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.

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.

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".

(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).

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

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

Your button Face should now looks like this:

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

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

Hopefully your button is starting to look better.

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:

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).

 

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 & 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 & adjusting the size.

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

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.

.

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 & the Face.

It is OK in the largest button, but lost, & 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 & 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.

Which has helped, & 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 & relationship of the Face & the Rim to their parent.

A Scale Transform & a Margin.

(One proportional to the scale of the object, & 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 & Y axis.

Now select the Rim element, & 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.

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" & while we are here, rename it "RimRadialGradient".

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

(This is neater, & 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 & 100.

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

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

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 & 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, & 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, & select the RimRadialGradient element.

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

Select the Gradient Tool in the left hand toolbar, & set as shown below

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

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

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

Set the head & 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 & 100 on the Ribbon.

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

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

But more contrast is required, & 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%.

 

But this only reduces the visibility & 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.

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

Change the Alpha for both of these to 90%.

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

Which hopefully should give something looking like this.

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 & 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%, & 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%, & not 100%, & 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!

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.

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%.

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, & using the using the Ellipse tool in the left hand tool bar.

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

Rename them "RimHighLightUpper" & "RimHighLightLower" respectively.

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, & set a Radial Gradient Fill, with white Gradient Stops at 86, 94 & 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.

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

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, lets apply an Opacity Mask, that only shows the part we want.

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

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

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

Select the RimHighLightUpper element, & 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 & 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 & 75, & the Alpha of each to 0% & 100% respectively.

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

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

Offset & enlarge the gradient to look like the image below.

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

The highlights are maybe a bit strong, & need a bit of adjustment.

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

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

So lets go back to the Face & 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 & 100 on the Ribbon.

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

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

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

Hopefully your Artboard looks something like this:

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

And the Face has an attractive border & 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, & 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".

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

Rename this Grid to "Inner", & 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 & Y axis.

Select the InnerBGround element, & remove the Stroke.

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

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", & 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" & "InnerGlossHighLight", remove the Stroke on both elements.

Now hide the InnerGlossHighLight element, & select "InnerEdgeShadow".

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

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

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

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

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

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

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

(You could set the Gradient Stops anywhere on the Ribbon, & 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 & 50 on the Ribbon.

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

Using the Gradient Tool, ensure the gradient looks the image below.

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 affective, it just depends on what you prefer & 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, & in the Transform section of the Properties tab, change the Rotation Angle to 45%.

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

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

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

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

Your buttons should now look like this:

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", & 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 & see that the Gradient Tool is now visible.

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

Select the RimHighLightLower element, & change the Opacity to 50%.

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

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

Section 5 - Interaction & Animation 

Now we have an attractive button, it is time to breath life into it, by adding some Interaction & 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 & an Inner.

We can easily introduce an overlay to affect the colour of each of these components, so lets start with the inner.

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

Now insert a new Ellipse, & name it "InnerOverlayColour".

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

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

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

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

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

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

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

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

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

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.

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

Ensure the Style is selected in the Objects and Timelines.

Now change the Background & BorderBrush colours of your Style.

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

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

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.

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

During the various mouse states, & how do we set these states?

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

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

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

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, & set the Opacity to 0%.

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

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

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.

Run your application & 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 & green colour blind.

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

Select the Face element, & with MouseOver state selected.

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

Select the Pressed state, & 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, & set the Opacity to 30%.

Now check your results & 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 sided.

Run your application & 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, & select the EasingFunction "Back Out".

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, & the InnerOverlayColour element.

Now open the Timeline by clicking the Show Timeline icon.

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).

Now move the Timeline to 0.8 seconds, & 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 & the end are the same).

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

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

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

Now your glow & 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, & 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 & shrink as it fades in & out).

Which we could try & 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 & grow the element. - Not very desirable.

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

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

(Just as we did for the InnerOverlayColour element).

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, & test the results.

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

Resulting in a more realistic electric light bulb glow & 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, & at a duration of 0.8 seconds.

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

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, & insert an Ellipse within this element, & 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.

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%, & 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, & a stronger glow & 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 & set up an animation just as we have before for 1.6 seconds.

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

Run your application & 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, & 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, & 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 & could leave it.

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

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

But a quick & 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 & Timelines.

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

 

Now set a Scale Transform for both the X & 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, & in the MouseOver & 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 & final touches 

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, & would make no sense to do so anyway.

(It would change the colour of every object, item & 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, & in the Base state.

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

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

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

So select InnerOverlayColour & select the Opacity Mask.

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

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

Now go back to the InnerOverlaySecondColour element, & select the Opacity Mask.

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

Now the bright purple is toned down, lets animate the Fill of this element.

Select the MouseOver state, & change the Fill to bright green.

 

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, & hit delete.

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

These are the values set in the Base state, & 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).

And once again for the Opacity of the InnerOverlayColour element.

Next, ensure you have the InnerOverlaySecondColour element selected.

Go to the Pressed state, & set the Opacity to 0%.

Run your application and review that results.

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, & run the application again.

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.

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%, & 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, & us setting a suitable duration.

So remove the EasingFunction, & set the Default transition to 0.5 seconds.

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, & set a Scale Transform in both the X & Y axis of 1.05.

Now run your application & see what you think.

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

Now there are lots 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 & 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 & 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 & uniform to all your Controls, & its primary role is an aid, not a toy.

(But that is my opinion, & 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, & insert a new Ellipse named "FocusVisualElement".

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

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

Then select the Focused state, & set the Opacity to 100%.

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

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

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

Now run your application, select the button to give it Focus & test the Normal, MouseOver & 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.

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, & 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.

You might be thinking that we could put the Focus, between the Rim & 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, & in the Base state, place a new Ellipse in the element named Rim.

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

Now set the Opacity to 0% in the Base state, & 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", & position as shown.

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

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

Content

Because of the visual style of this button, it is un-lightly 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, & in the Base state, change the Visibility from Collapsed to Visible.

Now hopefully your buttons will look like this.

Run the application, & 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.

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

The animation change is hardly noticeable in the running application, as the text is too small, & 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 & 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, & 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, & 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, & while in the Base state, set a Scale Transform for both the X & Y axis of 1.25.

This will bring the Font Size back inline with the default settings of the button Style, & 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.

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

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

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

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), & suitably adjusted for this UserControl.

So change the Font Size to 11 in the Style, Run the application, & decide for yourself.

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).

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

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

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

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

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

And that I think is the end!

Here is the completed button with the 3 recommended updates.

Download TestButtonComplete.zip - 188.11 KB

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 & 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, & 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

Here is my second Article/Tutorial: "Arcade Button"

And here is my third Article/Tutorial: "Picture Frame Control"

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

License

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

Share

About the Author

Alan Beasley
User Interface Analyst
United Kingdom United Kingdom
I've been playing with computers since my first Acorn Electron, & after blowing up a few ZX Spectrums. I moved on to the C64 & Amiga, & eventually reluctantly on to the PC.
 
I have learnt a wide set of skills during my 38 years of existence, living in the UK, on the sunny south coast.
 
My main area of expertise is Graphic/Visual Design, Usability & UI Design. I am not a programmer, but am fairly technically minded due to studying Mechanical Engineering at Uni.
 
I have work both Freelance & for IBM as a Graphic Designer, & am skilled in the usual graphics packages like, PhotoShop, CorelDraw or Illustrator, Premier, Dreamweaver, Flash etc.
But I originally started with Lightwave & 3D animation.

Comments and Discussions

 
GeneralMy vote of 4 PinmemberMember 1003442213-Jun-13 1:25 
GeneralWOW aMazing PinmemberNillo1234-Jun-13 1:28 
GeneralWow! PinmemberAlessio.NET19-Feb-13 0:23 
GeneralMy vote of 4 Pinmembernhbcyz29-Dec-12 14:00 
QuestionVery nice PinmemberCIDev28-Nov-12 9:07 
GeneralMy vote of 5 PinmemberIbrarM1-Jun-12 0:56 
GeneralMy vote of 5 PinmemberMazen el Senih3-Apr-12 7:18 
GeneralMy vote of 5 PinmvpNick Polyak21-Mar-12 5:43 
Question写得非常不错 Pinmemberbatsword19-Mar-12 22:09 
GeneralMy vote of 5 PinmemberFrank Heimes5-Nov-11 17:48 
QuestionCopied Buttons Do Not Resize Help! PinmemberRIckLedesma5-Jul-11 17:22 
GeneralMy vote of 5 Pinmembertcc7tcc719-Apr-11 13:01 
GeneralMy vote of 4 Pinmemberelkhantar14-Feb-11 21:04 
QuestionCan i add this buttons in C# forms? Pinmembergr-chaos23-Jan-11 11:56 
GeneralGreat!! Pinmemberjadughar21-Dec-10 4:20 
GeneralAwsome Article PinmemberMarcos Vanegas11-Sep-10 18:16 
GeneralRe: Awsome Article PinmemberAlan Beasley13-Sep-10 9:23 
GeneralAwesome Post Pinmemberahmad2x41-Sep-10 3:52 
GeneralRe: Awesome Post PinmemberAlan Beasley13-Sep-10 9:22 
GeneralProblem following the tutorial PinmemberIan Durward8-Jun-10 4:12 
GeneralRe: Problem following the tutorial PinmemberAlan Beasley8-Jun-10 6:47 
GeneralButton Idea PingroupNorm .net4-May-10 20:56 
GeneralRe: Button Idea PinmemberAlan Beasley4-May-10 23:09 
GeneralRe: Button Idea [modified] PingroupNorm .net4-May-10 23:46 
GeneralRe: Button Idea PinmemberAlan Beasley5-May-10 0:15 

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
Web01 | 2.8.140926.1 | Last Updated 3 Apr 2010
Article Copyright 2010 by Alan Beasley
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid