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

10 Cool Buttons for Download in Expression Blend & Silverlight

, 13 Jul 2010
Rate this:
Please Sign up or sign in to vote.
The WC Door button, covering all the missing skills needed to create the buttons shown in my 1st tutorial. As well as all 10 buttons for download!

Introduction

Welcome to my fourth Beginners tutorial for Expression Blend & Silverlight.

And I ask for your vote, as I appear to be the only pure Graphics, or Silverlight styling person on CodeProject.

So you decide if I should be here or not!!!!

img21.jpg

This tutorial is to complete all the skills required, to construct all the buttons I have previously shown. And probably my ending article on the topic of building buttons. Although I have other examples, that would not have shown well as a static image, so did not include. But these deserve a tutorial of their own, so no promises on this being the last button & Vector Graphic tutorial. There is so much more to enjoy with Expression Blend, and far more complicated & interesting Controls to explore & master, like a ComboBox or ListBox for examples.

I will maybe to add, & extend this tutorial, based on the requests I receive. But only within the scope of Buttons!

In my first 2 tutorials, I initially thought I had covered just about everything needed, to create all the buttons shown. Except for maybe Paths, Paths Operations, & Corner Radius's, which were used in the WC Door button. So was initially reluctant to do any more button construction tutorials, & fearful of just repeating myself. This has turned out not to be the case, so please read on!

 

Overview

Before commencing this tutorial, I recommend that you read my previous CodeProject tutorials.
I am writing them as a series, & as such this tutorial will presume prior knowledge.

Lesson 1 - "Building Better Buttons" (A beginners guide).

Lesson 2 - "Arcade Button" (How to control the position of elements in a Control Template).

Lesson 3 - "Picture Frame Control" (What is a Control, & why use one?)

 

Toilet (WC) Door Button (Restroom Button)

Section 1 - Making the Base Plate

Section 2 - Screwing the Base Plate down

Section 3 - Forming the Lock Face (Pastry Cutting)

Section 4 - Information Spinner (Engaged/Vacant)

Section 5 - Finishing the Face (Centre Pin & Spinner Recess)

Section 6 - Final Touches

Section 7 - Animation (Button States)

Section 8 - Summary

Section 9 - Source

Section 10 - Notes

 

Section 1- Making the Base Plate

Set up a new project called "WCDoorButton", or something similar.

(Or load up the saved "BlankButtonTemplate" you saved in the previous tutorial/lesson).

Either way, set up 6 buttons as I have shown in my previous tutorials.

(Ensure you rename, or make another copy of your "BlankButtonTemplate" project to preserve it).

Select one of the buttons, right click and choose Edit Template > Edit a Copy.

Name this new Style as "WCDoorButton", & apply this Style to the other 5 buttons.

(Use Return Scope to come out of the Control Template).

If you loaded the BlankButtonTemplate project, you already have the ArcadeButton Style applied to all your buttons.

Which you could have just renamed to "WCDoorButton", rather than create a whole new Style.

You can do this, as well as remove any unwanted Styles in the Resources tab.

So with everything setup, let us begin with a blank button Template, except for the ContentPresenter.

With the Grid element selected, drag out a Rectangle to fill the Template.

Ensure it is set to Stretch, & the Margins are Reset.

(Or double click the Rectangle Tool in the tool bar, to insert one with these settings as the default).

Rename the Rectangle to "BaseBGround", right click & Group into > Grid, rename the Grid to "Base".

Select the BaseBGround element, & duplicate it twice.

Rename these to "BaseFace" & "BaseTexture".

img6.jpg

These 3 elements will be all we need, to setup the Base. (The back part of the door lock).

Go to the Style now, & set a dark blue for the Background colour.

(The default: #FF1F3B53 (Hex Value) will do fine - Copy & Paste straight into Blend).

Back in the Template, set the Fill of the BaseBGround element, to Template Binding > Background.

Remove the Stroke, & then hide the BaseTexture element by clicking on the Eye icon next to it.

Next select the BaseFace element, remove the Stroke, & set the Opacity to 20%.

Now apply a ScaleTransform to the BaseFace element, of 0.95 for both the X & Y axis.

The whole reason for this element, is to simulate the flat face of the Base.

And the tapered edge of the Base, to be simulated, by revealing the element behind around the edge.

img7.jpg

(The edge will only be a couple of pixels wide, so not worth applying any gradients effects to accentuate it).

We want this edge detail to be a suitable width for all the button sizes, which we have discussed previously.

So we can control the edge with either: Margins, a ScaleTransform, or Grid dividers.

We also want rounded corners, on the Base Plate, so let us look at this first.

Select the BaseBGround element, & in the Appearance section of the Properties tab, set the X & Y Radius to 6.

imgB.jpg

This obviously, will apply a 6 pixel corner Radius for all the button sizes.

Which is probably about the right sized Radius in the medium sized buttons, but not largest or smallest.

img9.jpg

Once again, we have a property that: Does not Scale!

So how are we going to fix, or address this issue this time?

If you are editing the Control Template of the largest button, set the corner Radius of BaseBGround, to 10 pixels for both X & Y .

(Use lower pixel values, if you are editing the smaller button Control Templates).

Now right click on the BaseBGround element, & choose Path > Convert to Path.

9a.jpg

(Keep a close eye on the Artboard & the smaller buttons, see how the corners change).

All the buttons now have a proportional corner Radius.

As they have copied their relative proportions from the Control Template we were editing.

Now select the BaseFace element, & set the Margins to 1 on all sides, to help the edge spacing of the smallest buttons.

Next select the BaseFace element, & set a corner Radius of 8 pixels for both the X & Y Radius's.

(We need lower values than we used for the BaseBGround element, because of the ScaleTransform & the Margins).

Convert the BaseFace element to a Path, just as you did for the BaseBGround element.

Now just to fine tune, change the ScaleTransform on the BaseFace element to 0.97 for both the X & Y axis.

I'm happy with the setting for all the button sizes now, as shown in the image below.

imgD.jpg

(Feel free to adjust your setting as you see fit).

Now select the BaseTexture element, unhide it & remove the Stroke.

Apply the same corner Radius's you used for the BaseBGround element, & then convert it to a Path.

Set the Fill of the BaseTexture element to a Linear Gradient, & to a diagonal orientation using the Gradient Tool.

imgF.jpg

I like to set the StartPoint to 0,0, & the EndPoint to 1,1 to ensure I'm exactly at 45%.

img10.jpg

(Probably over the top for accuracy, & an obsessive compulsive disorder, but it makes me happy!).

Set both the Gradient Stops to white, & add another 5 Gradient Stops.

Leave the first Gradient Stop at 100% Alpha, set the second to 0% Alpha, & repeat along the Ribbon.

img11.jpg

With the Gradient Stops adjusted as shown in image above, your Base should look like the image below.

img37.jpg

(Don't get carried away with adjusting the Gradient Stops, as most of the Base will be hidden).

Set the Opacity of the BaseTexture element to 40%, & that is the Base finished!

What you should have learnt from the above steps, other than the corner Radius not Scaling.

Is that the Rectangle Tool/Control is "basically" an inherited Control, based on a Path that describes a rectangle.
But it has additional functionality, like the ability to adjust the corner Radius.

(The Border Tool/Control is similar, but has functionality to individually edit individual corner Radius, as well as the individual Edge/Stroke thicknesses).

 

Section 2 - Screwing the Base Plate down

Now let us make, & position the Screws located in each corner of the Base.

There are a number of ways we can create the Screw heads, & some will Scale, while others will not!

Do we want the Screw head detail to be proportional & Scale, or to be more pronounced in the smaller buttons.

The reason I ask, is because the easiest way to created the outer edge of the Screw head...

Would be to set an Ellipse with a Stroke of 1 pixel, but this will not Scale for all the button sizes.

This may be good enough in some situations, but not here. (Or for me!)

So instead, what we really want is to Scale proportionally, but also emphasis the edge in the smaller buttons.

Can we do it? Let us have a go and find out!

Select the Grid element, (Parent of the Base Grid element) & insert a new Grid.

Rename this Grid as "Screw1", ensure it is set to Stretch, & the Margins are set to 0.

Now select the Screw1 element, & choose Group Into > Grid, rename this Grid to "ScrewLayout".

img3.jpg

With ScrewLayout selected, set up Grid dividers as shown in the image below.

img4.jpg

(I have set my Grid dividers at 0.2*, 0.6* & 0.2* for both the Column & Row definitions).

Here is my XAML for the dividers, as shown in the image below.

img5.jpg

Now select the Screw1 element, & insert a new Ellipse to fill the Screw1 element. (Stretch, with 0 Margins).

Rename this element as Screw1BGround, remove the Stroke, & Template Bind the Fill, to the Background of the Style.

Hopefully in the Artboard, you have an Ellipse (Circle) filling the Base Plate, as shown in the image below.

img8.jpg

Now select the Screw1 element, & using the Selection Tool, resize it to only fill the top left section of the parent Grid.

Now Reset the Margins of the child element (Screw1BGround), to fit within the bounds of its parent.

The Artboard should look like the image below.

img13.jpg

Now set a ScaleTransform on the Screw1 element, of 0.6 for both the X & Y axis.

Next insert another Ellipse into the Screw1 element, & rename it to "Screw1Texture".

Set the Fill of Screw1Texture to a Radial Gradient, with white Gradient Stops at 90 & 91 on the Ribbon.

Leave the Alpha value of the first Gradient Stop to 100%, & set the Alpha value of the second to 0%.

Set the Opacity of the Screw1Texture element to 40%, & the Artboard should look like the image below.

img14.jpg

Now we have Screw edges that Scale with the button sizes, as well as the ability to soften the edge detail.

So select the Screw1Texture element, & change the Alpha value of the Gradient Stop at 91 on the Ribbon, to 30%.

(See how the contrast of the Screw edge is reduced).

This works great for the largest button, but is lost & washed out in the smallest button.

As we are basically dealing with fractions of a pixel. (Is that possible?)

So how can we enhance this for the smallest button?

(As setting a Margin of 1 to the Screw1Texture, is far too much).

(If only we could specify a fraction of a pixel - Oh I forget, we can!!!)

Margins do not have to be whole values, we can specify fractions as well!

(Within the bounds of Layout Rounding, which is basically: What to do with fractions of a pixel).

This can lead to off-centred positioning (As Blend & Silverlight does its best to render it).

But this can still work for us, & adds a bit of randomness to the Screw heads, which I like. (Why should it be perfect?)

So set the Margins of the Screw1Texture to 0.2 on all sides.

Now set the element Opacity of Screw1Texture to 60%, to make the Screw head standout a bit more.

With a bit of luck when you run your application (F5), the Screw head, should just about be visible in each button size.

img15.jpg

Now let us "Nudge" the Screw head over towards the centre of the button.

(But do this more in the smaller button, than in the largest button, but using Margins).

Select the Screw1 element, & set a Margin of 1 to the Top & Left only.

imgA.jpg

Run your application, & review the results.

imgB1.jpg

(You may prefer your Screw heads larger than mine).
(But I will leave mine as they are, or at least until I have created the centre parts of the button).

Now let us put a Slot in the Screw heads, which we could do with just a Path with 2 points.

And then set a Stroke thickness, but again this will not Scale...

(It sort of does when combined with a ScaleTransform, but not elegantly, so not discussed here)

So select the Screw1 element, & insert a new Rectangle. (Set to Stretch, with 0 Margins).

Rename this Rectangle to "Screw1Slot", remove the Stroke, & set the Fill to Template Binding > Background.

Now set a ScaleTransform on just the X axis to 0.1, & change the element Opacity to 70%.

Job done! But why did I not set a Linear Opacity Mask on the Screw1Texture element, to form the Slot?

(The problem with an Opacity Mask, is that we often cannot see the results in the Blend environment).

But before we play with the Slot angles, let us generate the other 3 Screws.

Select the Screw1 element, & duplicate it using Copy & Paste.

Using the Selection Tool, drag it to the Top Right corner of the parent Grid.

Set the Margins to 1, for both the Top & Right sides.

Repeat theses steps for the other 2 Screws, and remember to set the Margins accordingly.

Now rename all the duplicated elements as shown in the image below.

imgC.jpg

(Try to ensure good housekeeping, & logical naming).

Select the Screw1 element, & in the Transform section, set a Rotation of 35 degree's.

imgF1.jpg

Now set suitable angles, for the remaining 3 Screws.

img16.jpg

(I have used -60, -40 & 20 degree's)

And that is it for the Screws, except for recapping what we have learnt.

We can specify a fraction of a pixel.

And we can use Margins to "Nudge" things around, tailoring elements that suit different button sizes.

 

Section 3 - Forming the Lock Face (Pastry Cutting)

To form the Lock Face (Cover) of the door lock, we need to think about the top and bottom cut outs in the Lock Face.

I like to think of this as Pastry Cutting, where we make a Pastry Cutter, that we use on a piece of Pastry.

The Pastry is simply a Circle (Ellipse), but the Cutter is more complex, if we are to make the Path shape below.

img12.jpg

(Which is normally the way, as I generally spend more time making the Cutter, than I do the Pastry).

There are many ways to combine, & cut Pastry, and there are many tutorials online for this, covering all the major Vector Packages.

So I won't be covering how to do this, instead Download PastryCutter.zip I created in Expression Design.

Add the "PastryCutter" file to the project, by using Add Existing Item from the Project menu.

Now select the root element named Grid, & insert a new Grid, by double clicking on the Grid tool in the left hand tool bar.

(The Margins should be set to 0, and the Alignments set to Stretch).

Rename this new Grid to "LockFace".

Now go to the Projects tab, & double click on PastryCutter.xaml to open it.

In the Objects and Timeline, select the Path element & Copy it to the clipboard.

Now go back to the MainPage.xaml, (By clicking at the top of the Artboard)

Select the LockFace element, & Paste in the Pastry Cutter Path.

(You can now delete the PastryCutter.xaml from the Projects tab).

Select the newly pasted Path element, & Reset the Margins to 0.

Before we Scale this Path, to get the proportions correct, let us add a reference object (The Pastry).

Select the LockFace element, & double click on the Ellipse tool to insert a new Ellipse.

(Ensure the Margins are 0, & the Alignments are set to Stretch).

Select the Ellipse, & place it behind the Path, by dragging it above it, in the Objects and Timeline.

img17.jpg

Set the Fill of the Ellipse to white, & ensure the Stroke is removed.

Now apply a ScaleTransform of 0.9 for both the X & Y axis.

Next select the Path element, & set a ScaleTransform of 0.68 for the X axis, & 0.91 for the Y axis.

That should give you the same as the image below.

img18.jpg

(I have set the Opacity of the Path element to 50% for clarity).

Now "Shift" select, both the Path element, & the Ellipse element. (In that order!)

Go to the Object menu, & select Combine > Subtract, (As shown in the image below).

img19.jpg

(The element order selection is important: Select the Cutter, Apply to the Pastry).

With a bit of magic, you now have a Pastry Ellipse, with the shape of the Cutter Path removed.

img20.jpg

(This new "Sweetie" shaped Path, is not working for all the button sizes, but that is a minor Margin issue).

Rename the Path element to "LockFaceBGround", Reset the Margins & set the Fill to Template Binding > Background.

All our buttons should now look like the image below.

img1A.jpg

Once again we need a reference to Scale the Sweetie shape, but we need multiple elements in this style the part of the button.

As such, we should apply the ScaleTransform to the parent object LockFace, & subsequently all of its children.

So select the Root element Grid, insert an Ellipse, & place it behind the LockFace element.

Remove the Stroke, ensure the Fill is white (for clarity), & apply a ScaleTransform of 0.9 for both the X & Y axis.

Now to aid in setting the right ScaleTransform, select the LockFace element, & set the Opacity to 50%.

With the LockFace element still selected, set a ScaleTransform in the Y axis, to match the Ellipse behind it.

(I found that a ScaleTransform of 0.666 in the Y axis worked a treat! - No, I am not the Devil, Yet!).

Select the LockFaceBGround element, & duplicate it to create a new element, of type Path in the LockFace parent.

Change the Opacity of the LockFace element back to 100%, & rename the new duplicated Ellipse to "LockFaceTexture".

Now obviously we already have a texture effect applied to the Base, so select BaseTexture & convert the Fill to a New Resource.

Rename this New Resource to "WCDoorButtonTexture".

(If you are using Resource Dictionaries with multiple buttons in it, it pays to name tour Resources accordingly)

Back with the LockFaceTexture selected, change the Fill to this newly created Resource.

Change the element Opacity of LockFaceTexture to 40%, in an effort to reduce the contrast.

But reducing the contrast, makes the Lock Face darker, so duplicate the LockFaceTexture again.

Rename this new element to "LockFaceEdgeOverlay", set the Fill to Radial Gradient.

Change both the Gradient Stops to white, & add another at 90 on the Ribbon.

Select the Gradient Stop at 100 on the Ribbon, & change the Alpha value to 0%.

Using the Gradient Tool, change the shape to match the Ellipse (Circle) behind.

img1C.jpg

For the moment, that is the Lock Face sorted, let us think about the Rotating (Spinning) disc next.

 

Section 4 - Information Spinner (Engaged/Vacant)

Select the white Ellipse, & select Group Into > Grid.

Rename the Grid to "Spinner", & the child Ellipse to "SpinnerBGround".

Reset the ScaleTransform of 0.9 applied to SpinnerBGround back to 1.0.

And set a ScaleTransform of 0.85, to the Spinner Grid element, as well as a Margin of 1 on all sides.

That should space the Spinner nicely within the Lock Face, as shown in the image below.

img1D.jpg

We need to now generate 4 different images for the Spinner.

(An "Engaged", a "Vacant", a Green colour, & a Red colour).

As this Tutorial is about Expression Blend, & not Vector Graphic's, here are the "Vacant" & "Engaged" Paths.

(I want to stop this Tutorial from rambling on...).

Add these 2 Existing Items to the Project. & in the Projects tab, double click on the Engaged.xaml to access it.

Copy the Path element, & return to the MainPage, by clicking at the top of the Artboard.

Select the Spinner element in the button Template, & Paste the Path element.

Rename this Path element to "SpinnerEngagedText", Reset the Margins, & set the Width & Height to Auto.

img1E.jpg

We will position the SpinnerEngagedText element, with the help of a Grid, & then Rotate the parent Grid.

(Without the parent Grid, the Path element would rotate around its own centre, which would not be the centre of the Spinner).

Select the SpinnerEngagedText element, right click & choose Group Into > Grid.

Rename the Grid element to "SpinnerEngaged", set up Grid dividers, as shown in the image below.

img23.jpg

Position the SpinnerEngagedText element, inside these new RowDefinitions.

I found that RowDefinitions at 0.02*, 0.25* & 0.73* worked for me, as shown in the XAML below.

img24.jpg

Now set up some ColumnDefinitions at 0.225*, 0.54* & 0.235*.

img25.jpg

(The Column dividers are slightly off centre, to help centre the SpinnerEngagedText element).

Position the SpinnerEngagedText element inside these dividers, so it looks like the image below.

img26.jpg

(I have applied a 0.5 degree Rotation on the SpinnerEngagedText element to tweak it a little).

We need to do the same for the Vacant part of the Spinner, so Copy & Paste the SpinnerEngaged element.

Rename this duplicated Grid to "SpinnerVacant", & Delete the child Text element.

Select the original SpinnerEngaged element, & to move it out the way Rotate it 90 degree's.

(Which should hide it behind the right side of the LockFace).

Now find the Vacant.xaml file & Copy the Path to the SpinnerVacant Grid.(as you did for the Engaged Path).

(You can remove the Vacant.xaml from the Project now).

Rename the Vacant Path element to "SpinnerVacantText", & position it within the Grid dividers.

img28.jpg

Surprisingly, that seems to fit quite well, although the Text is larger than the "Engaged" Text.

(Change the Opacity of the LockFace to 50%, to reveal the "Engaged" Text).

Change the Row & Column dividers as you see fit, & remember to Reset the Margins of the child element.

I will leave mine as it is, other than to Rotate the SpinnerVacantText element -0.5 degree's.

This just leaves us, the Red & Green indicators to consider.

And we can use the LockFace (Pastry), as the basis for these elements.

So select the LockFaceBGround element, & use Copy & Paste to make a duplicate in the Spinner Grid.

Rename this new element to "SpinnerRed", Reset the Margins & ensure the Alignments are set to Stretch.

Change the ScaleTransform to 0.95 for the X axis, & 0.6 for the Y axis.

Now in the Objects and Timeline, hide the LockFace elements, by clicking on the Eye next to it.

Reset the Fill of SpinnerRed, & set the Fill to a Linear Gradient.

Using the Gradient Tool, arrange the arrow, as shown in the image below.

img2A.jpg

Change the first Gradient Stop to a Rich Red (#FFD20000), & place it at 49 on the Ribbon.

Set the other Gradient Stop at 50 on the Ribbon, & set the Alpha value to 0%.

This should give you the same as the image below.

img2B.jpg

Now duplicate the SpinnerRed element, rename it to "SpinnerGreen" & rotate it -90 degree's.

Change the Red Gradient Stop to a Rich Green (#FF00B400), & that is it for the Spinner.

Unhide the LockFace elements, and review the results, as shown in the image below.

img2C.jpg

Now select the Spinner element, & Rotate it 90 degree's, Opp's! -90 degree's to show the Engaged states.

(Maybe it would be better to have this work with positive values of Rotation)

Reset the Rotation back to 0, select the SpinnerEngaged element & change the Rotation to -90 degree's.

Next select the SpinnerRed element, & Rotate it 180 degree's.

That should mean, we can now Rotate the Spinner element 90 degree's, to show the Engaged state.

As shown in the image below.

img2D.jpg

And that is it for the Spinner. (This time, or at least for the moment)

 

Section 5 - Finishing the Face (Centre Pin & Spinner Recess)

Let us start with the Centre Pin, which should be pretty simple.

(I know I constantly spell "Center" wrong, but I'm English, Sorry!)

Select the Root element in the Objects and Timeline, insert a new Ellipse & rename it to "CentrePinBGround".

Set the Fill to Template Binding > Background, & remove the Stroke.

Group the CentrePinBGround element into a Grid, & rename the Grid to "CentrePin".

Set a ScaleTransform on the CentrePin Grid to 0.25 for both the X & Y axis.

(I want the Centre Pin to be quite small, & to grow during MouseOver).

Now insert a new Ellipse into the CentrePin Grid, & rename it to "CentrePinOverlay".

Set the Fill to a Radial Gradient, with white Gradient Stops at 0, 85 & 100 on the Ribbon.

Leave the Alpha value of the first Gradient Stop at 100%, change the second to 85%, and the third to 40%.

Now set the element Opacity to 60%, and fingers crossed, it should look like the image below.

img2E.jpg

Select the CentrePin Grid element again, insert a Rectangle, & rename it to "CentrePinSlot".

Set the Fill to Template Binding > Background, & remove the Stroke.

Apply a ScaleTransform of 0.1 for the Y axis, & set the element Opacity to 60%.

Job done, & should look like the image below.

img2F.jpg

Now to create a recessed dish area in the Base, that the Spinner can sit in.

(Which needs to sit in front of the Base, & behind the Spinner).

So select the Root element, & insert an Ellipse, rename it to "DishBGround".

Now group the DishBGround into a Grid, & rename the Grid to "Dish".

Next in the Objects & Timeline, drag the Dish Grid above the Spinner Grid.

img30.jpg

Select the DishBGround element, remove the Stroke, & set the Fill to Template Binding > Background. (As usual!)

Now select the Dish element, & set a ScaleTransform of 0.9 for both the X & Y axis.

Insert another Ellipse in to the Dish element, remove the Stroke & set the Fill to a Radial Gradient.

Reverse the Gradient Stops, move the white Gradient Stop to 93 on the Ribbon, & set the element Opacity to 30%.

And that should be basically it, as shown in the image below.

img31.jpg

 

Section 6 - Final Touches

I have resisted from applying any indication of light direction up until now, as it would be futile until we have all the elements in place.

Also the LockFace needs a little more edge definition, as does the CentrePin.

But I am not here to repeat effects & techniques, that I have shown in previous tutorials.

So I won't be covering these in this tutorial, other than to say:

Try some DropShadow Effects. - The rest is up to you!

(Or check my finished version, if you get stuck!)

Look at the Stroke I have applied to the Lock Face to make the edge stand out a bit.
As well as how I have created the Slot in the Centre Pin

Check out the Shine I have applied to the Spinner & Dish elements. 

 

Section 7 - Animation (Button States)

Now before I start playing with the VSM (Visual States Manager), let us consider what type of button this is?

It is currently a standard button, but the function of this Control would better suit a Toggle button.

A Toggle button has CheckStates, which allows us to set visual States for Unchecked, Checked & Intermediate.

img32.jpg

(For example, a CheckBox also has these 3 CheckStates).

The first 2 States, are fairly self explanatory, the button can be in a Pressed, or Not-Pressed State.

But the third Intermediate State is a little more complex, & can be considered as Half-Pressed.

(Not completely accurate, & before I upset too many developers, remember this is a beginners tutorial).

Consider that I have a Toggle button on a page that indicates "Yes" or "No".

But because of other options I have selected on the page, "Yes" or "No" may not be appropriate for these options.

If "Yes" or "No" is not applicable for the selected options, I need another State to define "Not Applicable" or "Not Sure".

Hence the Intermediate State! - (And that is my "Noddy" explanation for Designers, on the Intermediate State).

(You may think that the Disabled State would work, but Disabled & "Not Sure" are completely different).

So how do we turn this button into a Toggle button? - To be honest, I don't know!

I'm not sure there is a way of simply converting it, not for a Designer anyway.

But there is no real need, as we can just Copy & Paste, all the elements from a Button Template, to a Toggle Button Template.

You could also select the Root element of the Button Template, right click & choose Make Into Control, based on a Toggle Button.

But this will place a Toggle Button, within a Normal Button. (Resulting in nested Controls)

So Copy the Root element of our current Button Template, come out of the Template, & delete all 6 buttons.

(Do not worry, all our work is still on the Clipboard!)

From the Assets library, place a Toggle Button on the page, & edit the Template.

Name the new Style to "WCDoorToggleButton", & click OK.

Delete everything in the Template, with the exception of the ContentPresenter.

(If at all, we would rather use the ContentPresenter that came with this Template, rather than the one we are Pasting in).

(As it is already hooked up to the Style with Template Binding)

Select the Root Grid element, & Paste in all the element from the old Template.

You will probably have at the Root, a Grid within a Grid, so Copy & Paste, to arrange as shown.

img33.jpg

(We probably won't use the ContentPresenter, but why delete it? You never know?)
(We could also bring it to the front, & leave the Content empty in the Style? - You decide!)

Now come back out the Toggle Button Template, & using Copy & Paste, set up 6 buttons just as we had before.

Now for some animation, and this time, we are going to ignore the Pressed State in the VSM.

Instead we are going to use the Checked State, as the Pressed State.

So go to the Visual States Manager (VSM) tab. (Top Left of Blend - In Layout Mode)

Go to the Checked State, & Rotate the Spinner element 90 degree's.

Setup a Duration of 0.5 seconds, & run your application (F5).

Hopefully your WC Door Lock will now, animate between the Vacant & Engaged States.

Now we need to animate the CentrePin to Rotate along with the Spinner.

So in the Checked State, Rotate the CentrePin 90 degree's.

Next go to the MouseOver State, & change the CentrePin ScaleTransform from 0.25, to 0.35.

Repeat the above step in the Pressed State, to stop the CentrePin from shrinking during a button press.

Set a Duration of 0.2 second for the above States group, & run your application (F5) to review the results.

We could add some EasingFunctions for the 2 different State groups, so go play!

(Look at my finished version to see what I did)

Moving on, let us consider what if we only wanted the round central part of our button, to accept mouse events?

So that clicking on the Base, & associated Screw does not trigger the button.

All we need to do, is turn Off the "IsHitTestVisible" property for these elements. & their associated children.

So select the Base, & in the Advanced Properties of the Common Properties, turn Off the IsHitTestVisible.

img35.jpg

Repeat the above step for the ScrewLayout element, run your application to review the results.

Hopefully your Toggle Button, will now only accept mouse events in the inner circular area.

 

Section 8 - Summary

What I hope we have learnt in this tutorial, is not just a repeat of what I have shown before.

Instead I hope you have leant, that good layout & logical naming is important, as the Control becomes more complicated.

I grouped just about everything within a Grid, & a Grid is your best friend with regards Layout.

It keeps everything tidy, as well as providing power (parental control) over the child elements.

If I did not group things logically, I would have to hunt around to make portions of the Control, not IsHitTestVisible.

This is obviously also true, when it comes to animating parts of the Control in the VSM!

So don't be lazy, it will kick you later!!!

Now even thought we have created this button, based on the parameters I have specified.

I would not say it is the finished article, as I also, have just created this from scratch.

(Not copying my existing example - doing it Rolf Harris Style!).

So you will find that my completed example, has been edited & enhanced, based on my own personal taste.

That is it for now, & thanks for reading, & voting!!!

Cheers,

Alan

 

Section 9 - Source

Here is the whole Project, with the Buttons within the UserControl.

Whole Project - Buttons10Update.zip - 234.04 KB

Here is just the Resource Dictionary, which will be hard to edit unless you place the Styles, back within the UserControl.

ResourceDictionary - 10RoundButtonsUpdate.zip - 21.87 KB

Section 10 - Notes

The Plunger button will Scale its plunger depth, based on it's size. Where the Arcade button did not.
This is because it user a change in Center Point & a Scale Transform, allowing it to Scale for all button sizes.

The Celtic Cross button, along with the WC button is a Toggle button.

I have used Blur Effects & Drop Shadows, at sizes that work well on average, but not excessive for smaller Scales. Some editing of these Effects based on size, will always be required.

 

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

 
QuestionMy Vote 5/5 Pinmembersanong20-Dec-13 20:53 
GeneralMy vote of 5 PinmemberKashif_Imran8-Aug-13 10:15 
GeneralMy vote of 5 Pinmemberim_tb@sina.com20-Aug-12 16:48 
AnswerRe: My vote of 5 Pinmembermla1547-Jun-13 4:53 
GeneralMy vote of 5 Pinmemberthomashiker1-May-12 18:00 
GeneralMy vote of 3 PinmemberSunil K V17-Apr-12 19:19 
GeneralMy vote of 5 PinmemberMember 38798489-Apr-12 7:10 
GeneralMy vote of 5 PinmemberNirav Chheda1-Mar-12 16:23 
GeneralMy vote of 5 PinmemberJohan Yimanto28-Jan-12 12:07 
GeneralMy vote of 5 PinmemberMr-H 201015-Jan-12 2:03 
GeneralMy vote of 5 Pinmembermr.mavir3-May-11 17:53 
GeneralCan you write it for WPF :( PinmemberXmen W.K.26-Apr-11 0:22 
GeneralMy vote of 5 Pinmemberpaul.d.mcswain20-Apr-11 6:19 
GeneralMy vote of 5 Pinmembertcc7tcc719-Apr-11 12:55 
GeneralMy vote of 5 Pinmemberterryd17-Nov-10 9:18 
QuestionInfo on use Pinmemberfabiocarucci2-Nov-10 6:58 
GeneralMy vote of 4 Pinmembermallon19-Oct-10 11:38 
GeneralMy vote of 5 PinmemberJohn321010-Oct-10 23:10 
GeneralMy vote of 5 PinmemberSaleem CB2-Sep-10 3:06 
GeneralRe: My vote of 5 PinmemberAlan Beasley13-Sep-10 9:26 
GeneralSimply Outstanding! PinmemberGreg Cadmes5-Aug-10 6:51 
GeneralRe: Simply Outstanding! PinmemberAlan Beasley5-Aug-10 10:04 
GeneralGreat Work PinmemberDareenH14-Jul-10 3:23 
GeneralRe: Great Work PinmemberAlan Beasley14-Jul-10 8:58 
GeneralExcellent Work - 5 from me PinmentorKunalChowdhury12-May-10 18:36 
GeneralRe: Excellent Work - 5 from me PinmemberAlan Beasley13-May-10 0:30 
GeneralGood article some suggestions on the title from SEO perspective PinmvpShivprasad koirala21-Apr-10 5:30 
GeneralRe: Good article some suggestions on the title from SEO perspective PinmemberAlan Beasley21-Apr-10 5:46 
GeneralRe: Good article some suggestions on the title from SEO perspective PinmvpShivprasad koirala21-Apr-10 6:27 
GeneralRe: Good article some suggestions on the title from SEO perspective PinmemberAlan Beasley22-Apr-10 23:50 
GeneralMy vote of 2 Pinmemberdonscott20-Apr-10 21:08 
GeneralRe: My vote of 2 PinmemberAlan Beasley20-Apr-10 21:55 
GeneralRe: My vote of 2 PingroupNorm .net23-Apr-10 0:33 
GeneralRe: My vote of 2 - Still waiting for your response??? [modified] PinmemberAlan Beasley29-Apr-10 21:49 
GeneralRe: My vote of 2 - Still waiting for your response??? Pinmemberluisnike197-Jun-10 4:24 
GeneralRe: My vote of 2 - Still waiting for your response??? PinmemberAlan Beasley7-Jun-10 7:26 
GeneralLove your work PinmemberKatka Vaughan19-Apr-10 0:31 
GeneralRe: Love your work PinmemberAlan Beasley20-Apr-10 3:54 
GeneralRe: Love your work PinmemberKatka Vaughan20-Apr-10 4:54 
GeneralSL is awesome PinmemberXmen W.K.8-Apr-10 16:57 
GeneralRe: SL is awesome PinmemberAlan Beasley9-Apr-10 3:56 
GeneralAnother outstanding Article Pinmemberlinuxjr8-Apr-10 16:05 
GeneralRe: Another outstanding Article PinmemberAlan Beasley9-Apr-10 3:52 
GeneralMore please, sir Pinmemberepaetz418-Apr-10 9:59 
GeneralRe: More please, sir PinmemberAlan Beasley9-Apr-10 3:42 
GeneralGood stuff PinmemberDouglas Troy8-Apr-10 6:48 
GeneralRe: Good stuff PinmemberAlan Beasley9-Apr-10 3:30 
GeneralExcellent job - now onto bigger and better things. PinmvpPete O'Hanlon8-Apr-10 4:23 
GeneralRe: Excellent job - now onto bigger and better things. Pinmemberdefwebserver8-Apr-10 5:49 
JokeRe: Excellent job - now onto bigger and better things. PinmemberAndrew Rissing8-Apr-10 6:50 

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