As I’ve described before, we introduced the new VisualStateManager concept into Silverlight WPF before we added the same functionality in desktop WPF, in violation of our general guideline that Silverlight is functionally a subset of the desktop .NET Frameworks. We are planning to add full VSM support on the desktop, but we haven’t had time to support all the existing controls and other infrastructure.
In the meantime, we would like to enable you to start prototyping desktop controls that use VSM and can therefore share templates and implementation with their Silverlight kindred. So, for prototyping only purposes, you will find attached to this blog entry the full source code for a desktop WPF implementation of VisualStateManager and a behavior system that allows existing WPF controls to work with it.
The solution contains a VisualStateManager project that implements VisualStateManager, VisualState, VisualStateGroup and the other classes that VSM requires, and a VSMTestApp project that produces a standalone exe that shows VSM templates applied to some Buttons and a custom WeatherControl.
Another reason for my blogging this project is that it is a powerful example of the Attached Behavior pattern. It might seem VisualStateManager needs to be added into the core of WPF in order to function, but as the project shows, it can be implemented through use of an attached property and change callbacks. To see how this works look in VisualStateManager.cs at the VisualStatesGroupProperty and VisualStateGroupsProperty_Changed callback.
Furthermore, the normal pattern for using Silverlight controls with VisualStateManager is to have the controls call GoToState() in their implementation code. But desktop WPF controls do not have these GoToState() calls. The solution is to create VisualStateBehaviors that use the Attached Behavior pattern again to inject the GoToState() calls in response to the proper events. Take a look in the Behaviors folder of the VisualStateManager project to see how this works. It includes the abilities to write your own VisualStateBehaviors to add VSM support into any control *without* modifying the control itself.
I plan to use this project to show how Triggers work with VisualStateManager in the future…stay tuned.
This prototype project is compatible with the VisualStateManager from Silverlight Beta 2. There is no guarantee this version will be compatible with VSM in the Silverlight RTM and there will be an officially support VSM for desktop WPF in the future. Please don’t use this code for production purposes, it is purely for experimentation and prototyping now.
Acknowledgements: Kenny Young, Kurt Jacob, Dave Relyea Karen Corby and Mike Hillberg all contributed to this project. Kenny in particular deserves credit for writing the original prototype that led to the features implementation in Silverlight. Karen Corby ported the custom Weather Control from her blog series on VisualStateManager. Any bugs in the project were introduced by me.