Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
752 views
in Technique[技术] by (71.8m points)

wpf - Binding [VisualStateManager] view state to a MVVM viewmodel?

How do you bind the VisualStateManager state of a control to a property in you viewmodel? Can it be done?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Actually you can. The trick is to make an Attached property and add a property changed callback that actually calls GoToState:

public class StateHelper {
    public static readonly DependencyProperty StateProperty = DependencyProperty.RegisterAttached( 
        "State", 
        typeof( String ), 
        typeof( StateHelper ),
        new UIPropertyMetadata( null, StateChanged ) );

      internal static void StateChanged( DependencyObject target, DependencyPropertyChangedEventArgs args ) {
      if( args.NewValue != null )
        VisualStateManager.GoToState( ( FrameworkElement )target, args.NewValue, true );
    }
  }

You can then set this property in you xaml and add a binding to your viewmodel like any other:

<Window .. xmlns:local="clr-namespace:mynamespace" ..>
    <TextBox Text="{Binding Path=Name, Mode=TwoWay}"
             local:StateHelper.State="{Binding Path=State, Mode=TwoWay}" />
</Window>

Name and State are regular properties in the viewmodel. When Name is set in the viewmodel, either by the binding or something else, it can change the State witch will update the visual state. State could also be set by any other factor and still it would update the view state on the textbox.

Since we're using a normal binding to bind to Status, we can apply converters or anything else that we'd normally be able to do, so the viewmodel doesn't have to be aware that its actually setting a visual state name, State could be a bool or an enum or whatever.

You can also use this approach using the wpftoolkit on .net 3.5, but you have to cast target to a Control instead of a FrameworkElement.

Another quick note on visual states, make sure you don't name your visual states so that they conflict with the built in ones unless you know what you're doing. This is especially true for validation since the validation engine will try and set its states everytime the binding is updated (and at some other times as well). Go here for a reference on visual state names for diffrent controls.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...