How to change VisualState via ViewModel [duplicate]

本小妞迷上赌 提交于 2019-12-18 03:46:21

问题


I know this Question is similar to many. Anyway, I don't understand.

I have a several VisualStates (more than 2, thats why DataStateBehavior is not my solution). And I have ViewModel, which have enum property CurrentState. Every enum value represents to one state, also may be several enum values represents to one states, doesn't metter. I want VisualState changed when the CurrentState changed (thought, that immediately appears in my mind : Binding was created exactly for this case!)

Can I bind CurrentState with view VisualState (xaml-only solution), to get the behavior described above?

If yes, how can I do it?

If no, how should I use VisualStateManager.GoToState() method in my ViewModel?


回答1:


I wouldn't use VisualStateManager.GoToState in the ViewModel for a number of reasons, the biggest being you have to pass in the control whose visual state you're going to change. Passing UI controls up to your viewmodel goes against the whole MVVM approach.

My suggestion is to use (for Windows 8 Store) Winrt Behaviours or to use the Blend system.windows.interactivity.dll (for same functionality) to take a VisualState name from a viewmodel and update an object. The code would look something like this:

ViewModel:

public string State{
    get{_stateName;}
    set{_stateName=value;
        RaisePropertyChanged("State");
}

View:

<Grid>
    <I:Interaction.Behaviors>
        <b:VisualStateSettingBehavior StateToSet="{Binding State}"/>
    </i:Interaction.Behaviors>
</Grid>

Behavior:

public class VisualStateSettingBehavior:Behavior<Control>
{

    StateToSet{
               get{GetValue(StateProperty) as string;}
               set{SetValue{StateProperty,value);
                    LoadState();}
}
private void LoadState()
{
VisualStateManager.GoToState(AssociatedObject,StateToSet,true);
}
}

What the behaviour is doing is connecting up to the control and allowing you, in a programmatic way, to extend its functionality. This approach allows you to keep the ViewModel separate from your View.




回答2:


I wanted to note a solution similar to @FasterSolutions', using built-in components of the Blend SDK.

Set a PropertyChangedTrigger on the view-model's "CurrentState" property, and add a GoToStateAction to change the visual state:

<i:Interaction.Triggers
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Inte‌​ractivity"  
    xmlns:ei="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microso‌ft.Expression.Interactions">
    <ei:PropertyChangedTrigger Binding="{Binding CurrentState}">
        <ei:GoToStateAction StateName="{Binding CurrentState}" />
    </ei:PropertyChangedTrigger>
</i:Interaction.Triggers>


来源:https://stackoverflow.com/questions/7190058/how-to-change-visualstate-via-viewmodel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!