I use the following attached behavior:
using System; using System.Windows; using System.Windows.Controls; namespace PixelLab.WP7.Common.Behaviors { /// /// Provides an attached behavior for binding visual states. /// public static class VisualStates { /// /// Identifies the CurrentState attached property. /// public static readonly DependencyProperty CurrentStateProperty = DependencyProperty .RegisterAttached( "CurrentState", typeof(string), typeof(VisualStates), new PropertyMetadata(TransitionToState)); /// /// Gets the current visual state of the specified object. This is an attached property. /// /// The source object. /// The current visual state of the specified object. public static string GetCurrentState(DependencyObject obj) { return (string)obj.GetValue(CurrentStateProperty); } /// /// Sets the current visual state of the specified object. This is an attached property. /// /// The target object. /// The new visual state. public static void SetCurrentState(DependencyObject obj, string value) { obj.SetValue(CurrentStateProperty, value); } static void startOnGuiThread( Action act ) { var disp = Deployment.Current.Dispatcher; if( disp.CheckAccess() ) act(); else disp.BeginInvoke( act ); } private static void TransitionToState( object sender, DependencyPropertyChangedEventArgs args ) { FrameworkElement elt = sender as FrameworkElement; if( null == elt ) throw new ArgumentException( "CurrentState is only supported on the FrameworkElement" ); string newState = args.NewValue.ToString(); startOnGuiThread( () => ExtendedVisualStateManager.GoToElementState( elt, newState, true ) ); } } }
In your view model, derive a property for the current visual state, and then on the visual element that you want to process with the visual state to use the following view to bind the visual state, for example
<phone:PhoneApplicationPage ... xmlns:common="clr-namespace:PixelLab.Common;assembly=PixelLab.Common" common:VisualStates.CurrentState="{Binding CurrentState}">
source share