Change VisualState based on property value

How to change VisualState based on property value in WP7?

I am trying to use the MVVM pattern, and when my model loads, I want my view to transition to a special VisualState.

In Silverlight, we have triggers for changing properties, but in WP7, no!

PS: I do not want to use frameworks. I want to understand how this is done in WP7.

+4
source share
2 answers

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}"> 
+8
source

Initially, the behavior of the DataStateBehavior looks perfect, and this article even specifically talks about using it with WP7.

However, in the Codeplex project, article links no longer have behavior, and the behavior is not in Expression Blend (at least for WP7 projects).

I would be inclined to display the property in the ViewModel and programmatically listen for changes in the view and change the visual state accordingly:

In the View constructor:

 ViewModelLocator.MainViewModelStatic.PropertyChanged += ViewModelPropertyChanged; 

Then create an event handler that changes state accordingly:

 private void ViewModelPropertyChanged(object sender, PropertyChangedEventArgs e) { if(e.PropertyName == MainViewModel.SomeProp) { // Change the state using the VisualStateManager } } 

Damian

+1
source

Source: https://habr.com/ru/post/1339884/


All Articles