4

我知道这个问题与许多问题相似。反正我不明白。

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

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

如果是,我该怎么做?

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

4

2 回答 2

9

我想指出一个类似于 @FasterSolutions 的解决方案,它使用 Blend SDK 的内置组件。

PropertyChangedTrigger在视图模型的“CurrentState”属性上设置 a ,并添加 aGoToStateAction以更改视觉状态:

<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>
于 2013-08-17T00:52:46.367 回答
8

出于多种原因,我不会在 ViewModel 中使用 VisualStateManager.GoToState,最大的原因是您必须传入要更改其视觉状态的控件。将 UI 控件传递给您的视图模型与整个 MVVM 方法背道而驰。

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

视图模型:

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

看法:

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

行为:

public class VisualStateSettingBehavior:Behavior<Control>
{

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

该行为所做的是连接到控件并允许您以编程方式扩展其功能。这种方法允许您将 ViewModel 与您的 View 分开。

于 2012-10-10T09:23:44.293 回答