Here we are – the final post of our Parts & States Model series for Silverlight 2 controls. Hope you’ve enjoyed the ride so far!
Today, we’ll go through some general recommendations on how to use the Parts & States model. We’ll also take a look ahead: VisualStateManager on Windows Presentation Foundation and future releases of Silverlight.
Parts & States Model Recommendations
1. Use the Parts & States Model with Custom Controls and UserControls
Like we mentioned in the first post, the Parts & States Model is just a pattern. It is not required by the runtime, and it’s perfectly fine to build controls without the Parts & States Model and VisualStateManager.
However, we do think this is a good model. And Blend will only be able to support skinning of custom controls using the Parts & States Model.
And while this series concentrated on VSM with Custom Controls, remember you can use it with UserControls as well!
2. Custom VSM xmlns
This one is less of a recommendation and more of a heads up.
Because of a known Silverlight 2 Beta 2 bug, you need to use a custom xmlns for VisualStateManager and its related classes.
For consistency across controls, we recommend the following naming convention.
4. CommonStates and FocusStates are special
Many controls define these two state groups:
If your control is going to have some or all of these states, for consistency, we recommend the above grouping and naming.
5. Be resilient to missing Parts & States in template
There are many reasons why a particular ControlTemplate might not supply a given part or state: the designer may have deliberately chosen to leave it out. He/she might not have created it yet. And so on.
It is good practice to prevent crashes or other catastrophic failures when a part is missing.
Note: The VisualStateManager.GoToState() method already takes care of this for states – it returns false when the target VisualState is not found.
6. Consider supporting “fallback” states
For complex controls, it is sometimes interesting to provide a fallback mechanism for particular states that do not exist.
The advantage of this approach are pretty intuitive: the control continues to visually function correctly when a designer hasn’t provided a particular state.
But there are also some significant negatives: the fallback states mechanism isn’t fully integrated into the Parts & States model, which means that Blend has no way of knowing about them.
So, please use fallback states sparingly and only when the control is sufficiently complex enough to warrants it.
Also, if you think this is a pattern that you’ll leverage often, let us know! We’d love the feedback.
7. Subclasses should only add states in new state groups (not existing state groups)
As you know, each state group is orthogonal. This makes it easy for a subclass to add new state groups. For instance, you can create a StackButton that derives from Button and adds a StackStates group:
This works because the StackStates state group logic is completely independent from the Button’s logic around CommonStates & FocusStates.
However, if you want to add a new state to an existing state group, the state group logic can become jumbled. It’s is difficult to guarantee that the right logical state checks will happen in the right order.
Let’s make this clearer with an example. BasicControl defines two states in its CommonStates: Normal, MouseOver. Its logical state machine is:
- if (mouse is not over control) goto Normal
- if (mouse is over control) goto MouseOver
Now, ExtendedControl derives from BasicControls and wants to add a Pressed state. The goal logical state machine would be:
- if (mouse is not over control) goto Normal
- if (mouse is over control AND mouse button is not down) goto MouseOver
- if (mouse button is down) goto Pressed
However, there is no good for way for ExtendedControl to add the (AND mouse button is not down) check for the MouseOver state, since that logic lives in the Button base class.
All this just means: Subclasses can always add new states to an new state group. But we recommend against adding new states to existing state groups.
Note: There are different ways (each with its own pluses & minuses) for the platform to address this limitation in a future version. We’re currently leaning towards a Triggers-based solution (yes, I said triggers). For more, keep reading.
VSM & Windows Presentation Foundation
Silverlight’s Parts & States Model leverages many features (like ControlTemplates, GetTemplateChild() helpers, etc) that already exist in Windows Presentation Foundation.
However, there are some features – namely VisualStateManager and its associated classes – that do not yet exist in WPF. The good news is that the next version of Windows Presentation Foundation will include VisualStateManager!
For some that are trying to move their Siverlight 2 controls & skins to WPF now, the next version of the .NET framework may feel a ways off. To help remedy that, we are currently looking into shipping a WPF assembly that contains VisualStateManager before the next full release of WPF. Plans are still early – and so the timeline & ship vehicle details are still being worked out.
More details as we have them!
Future Silverlight Features
One of the often asked questions about the Silverlight control model is: “Where are the Triggers?” In fact, it’s normally, “Where are the TRIGGERS?????” 🙂
There are a lot of different reasons why we were not able to bring Triggers into the Silverlight 2 release. The primary technical challenge was that our property system architecture is not sufficiently complex to support them. This will however change in a future version of Silverlight, and then we’ll be able to start supporting Triggers.
How would Triggers & VSM play together? The tentative design brainstorm looks something like:
The platform would provide a GoToState trigger action that causes VisualStateManager to initiate a state change to the desired state.
The designer would, then, have the option of using the built-in states that come with the control (and leaving the visual state change logic to the control). OR, he/she can take over and trigger all the VSM state changes from XAML. In the latter case, it would also be possible for the designer to add states to new or existing state groups that a control code does not know about.
Exciting stuff coming!
So that’s the end of our 4 part series on the Silverlight 2 Parts & States Model. If you have questions or feedback, we’d love to hear it.
If this series has wet your appetite for VisualStateManager, here are some more great resources:
- Christian Schormann‘s Blog (Group Program Manager for Expression Blend)
- Steve White’s video tutorials (Program Manager for Expression Blend)
- Celso Gomes’s tutorials (Designer for Expression Blend)
- Tim Heuer‘s Blog (Senior Program Manager on the .NET Developer Platform)
- Jesse Liberty‘s tutorials (Senior Program Manager on the .NET Developer Platform)
- Scott Guthrie‘s Blog (Corporate Vice President of the Developer Division)