如何通过ViewModel更改VisualState

stu*_*bax 3 c# wpf xaml visualstates

我知道这个问题类似于很多.无论如何,我不明白.

我有几个VisualStates(超过2个,这就是为什么DataStateBehavior不是我的解决方案).我有ViewModel,它具有枚举属性CurrentState.每个枚举值代表一个状态,也可能是几个枚举值代表一个状态,不符合.我希望在CurrentState发生变化时改变VisualState(想一想,我的脑海中立即出现了:Binding是为这种情况创建的!)

我可以将CurrentState与视图VisualState(仅限xaml解决方案)绑定,以获得上述行为吗?

如果是,我该怎么办?

如果不是,我应该如何在我的ViewModel中使用VisualStateManager.GoToState()方法?

McG*_*gle 9

我想要注意一个类似于@FasterSolutions的解决方案,使用Blend SDK的内置组件.

PropertyChangedTrigger在视图模型的"CurrentState"属性上设置一个,并添加一个GoToStateAction以更改视觉状态:

<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>
Run Code Online (Sandbox Code Playgroud)

  • 对于那些找不到e&ei的人,xmlns:i ="clr-namespace:System.Windows.Interactivity; assembly = System.Windows.Interactivity"xmlns:ei ="clr-namespace:Microsoft.Expression.Interactivity.Core ;装配= Microsoft.Expression.Interactions" (5认同)
  • 这些xmlns在VS2015中运行得更好:`xmlns:i ="http://schemas.microsoft.com/expression/2010/interactivity"xmlns:ei ="http://schemas.microsoft.com/expression/2010/interactions" ` (3认同)

Fas*_*ons 8

我不会在ViewModel中使用VisualStateManager.GoToState有很多原因,最重要的是你必须传递你将要改变它的视觉状态的控件.将UI控件传递给viewmodel违背了整个MVVM方法.

我的建议是使用(对于Windows 8商店)Winrt Behaviors或使用Blend system.windows.interactivity.dll(用于相同的功能)从视图模型中获取VisualState名称并更新对象.代码看起来像这样:

视图模型:

public string State{
    get{_stateName;}
    set{_stateName=value;
        RaisePropertyChanged("State");
}
Run Code Online (Sandbox Code Playgroud)

视图:

<Grid>
    <I:Interaction.Behaviors>
        <b:VisualStateSettingBehavior StateToSet="{Binding State}"/>
    </i:Interaction.Behaviors>
</Grid>
Run Code Online (Sandbox Code Playgroud)

行为:

public class VisualStateSettingBehavior:Behavior<Control>
{

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

行为的作用是连接到控件并允许您以编程方式扩展其功能.此方法允许您将ViewModel与View分开.