After converting my classy (or should I say glassy) mockup from Expression Design to Expression Blend, and making my Glass Ball into a Button I had to do a little bit of cleanup in the layout to get it scaling just how I wanted:
Here you can see I’ve used a grid with three rows to layout my button, the background ellipse is set to stretch Horizontally and Vertically with RowSpan=2 and I’ve locked the first two rows so that the sphere won’t actually resize. The first row is for the Specular Highlight geometry to stretch to. I’ve also made the grid a fixed width so that nothing stretches horizontally either. The third row just the drop shadow aligned to the bottom so if you resize the top of the button the drop shadow stays in place but the ball moves up and down (desired for some bouncy ball animation I intend to do with some buttons). The ContentPresenter is also set to RowSpan=2 so the button’s content will always be centered in the ball.
So having made this into a resource I could apply to any Button, my next step was to figure out, how to make it act like a button (It is pretty lifeless at the moment).
The first step to give it life is to add Hover state. At first I thought I’d simply animate the background to become a little bit lighter and that would be that. but then I realised that because the Fill brush of the ButtonBackground ellipse was a resource I couldn’t animate it… Hmmm…
After a little out of the box thinking I realised I could have two ButtonBackground ellipses one layered on top of the other, with the Normal brush applied to the one underneath and the Hovered brush applied to the one on top. Then I would simply animate the Opacity of the Hovered ellipse in and out when the IsMouseOver=true property is Activated and Deactivated.
Q: Why go to this trouble? Why not just convert the brush to a local value and animate the fill?
A: I was doing this originally, but I wanted to be able re-use this resource and simply apply styles to get different coloured buttons that act exactly the same. This way another button could easily have a "Red" style applied to point to different Brush resources, and all the animation would work the same.
So with the hover state working nicely my next step was to make it look like it was pressed down. The process for this was almost identical, simply add another ellipse but this time with a darker background instead of a lighter one.
I was initially animating at 100ms to the pressed state but I was finding even this wasn’t as snappy as I’d like and so I simply set moved the keyframes to 0ms for the pressed state.
This leads me a to a problem… Having a key frame at 0ms disables all subsequent animations. So once you’ve pressed the button it doesn’t hover anymore… bugger. The reason this is happening is because the Pressed animation is continuing to play while the Mouse over attempts to also, but is getting overridden. The way to overcome it is to add a Stop action for the storyboards that are continuing to play (Any storyboard with a Keyframe at 0ms).
I did a state for IsEnabled=false by setting almost all of the background and highlights to 50% opacity, the effect is the transparent ball (to the right).
When I’m happy with these buttons I might post the Xaml, let me know if you’re interested.