I’ve recently come up with a thing that is probably old news for most people. But to me it was new. I have styled a bunch of things lately, among them a bunch of buttons. Most of the buttons had MouserOver states, but no Pressed state. So I changed the template of the buttons and added my VisualStateManager (VSM from now on).
Being lazy as I am, I opened up generic.xaml and stole the original style for the button. And no, I did not use Blend! Why not? Probably because I’m a stubborn meticulous person who like coding things on my own…
Since I didn’t need the Pressed state and Disabled states, I basically just shorthanded them and closed their elements
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name="CommonStates">
<vsm:VisualState x:Name="Normal"/>
<vsm:VisualState x:Name="MouseOver">
<Storyboard>
// Animation
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="Pressed" />
<vsm:VisualState x:Name="Disabled" />
</vsm:VisualStateGroup>
<vsm:VisualStateGroup x:Name="FocusStates">
<vsm:VisualState x:Name="Focused" />
<vsm:VisualState x:Name="Unfocused" />
</vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>
After that I was happy. My style was complete. So I compiled and looked at the buttons in the browser. The looked nice…and they had mouse over effects. And then I pressed the mouse button… And the styling went bye bye… What!?
Ok…so I need to add the animation to the Pressed state as well to keep it… Well… No! Just remember to remove the Pressed state completely. Leaving it in the Xaml tells Silverlight that you want an effect. However the effect is returning the button to the original layout. Just as hat happens because you have your Normal state in there.
Another side note on the VSM for those of you who are new. The general idea is that only one state within a group can be active at anytime. However, the code doesn’t actually tell the VSM to activate a state in a particular group, but just a state. So a wrongly implemented control can actually cause some interesting effects. So remember to use “if/else if” and not several if statements as it can get odd results. So generally there will be one “if” or “else if” per state in a group and then a new “if/else if” for the next group if you implement it like Microsoft recommends…
So what does Microsoft recommend? Well, in general they seem to have bools keeping track of the states and then one method to do the actual setting. So the have one IsEnabled, one IsPressed, one IsMouse and so on and then one method called ChangeVisualState that sets the actual state. Then all state changing code sets the bools and call that method. That makes for a logic that can be relatively simple to follow and debug…