我知道问题类似于很多。无论如何,我不明白。
我有几个 VisualStates (超过2个,这就是为什么 DataStateBehavior 不是我的解决方案)。我有ViewModel,它具有枚举属性 CurrentState 。每个枚举值代表一个状态,也可能是几个枚举值代表一个状态,不符合。当 CurrentState 发生变化时,我希望 VisualState 发生变化(想到,我脑海中立刻出现了这样的情况: Binding是为这种情况完全创建的!)
我可以将 CurrentState 与视图 VisualState (仅限xaml解决方案)绑定,以获得上述行为吗?
如果是,我该怎么做?
如果不是,我应该如何在 ViewModel 中使用 VisualStateManager.GoToState()方法?
答案 0 :(得分:8)
我不会在ViewModel中使用VisualStateManager.GoToState有很多原因,最重要的是你必须传递你将要改变的视觉状态的控件。将UI控件传递给viewmodel违背了整个MVVM方法。
我的建议是使用(对于Windows 8商店)Winrt Behaviours或使用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分开。
答案 1 :(得分:8)
我想使用Blend SDK的内置组件注意类似于@FasterSolutions的解决方案。
在视图模型的“CurrentState”属性上设置PropertyChangedTrigger
,并添加GoToStateAction
以更改视觉状态:
<i:Interaction.Triggers
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ei="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions">
<ei:PropertyChangedTrigger Binding="{Binding CurrentState}">
<ei:GoToStateAction StateName="{Binding CurrentState}" />
</ei:PropertyChangedTrigger>
</i:Interaction.Triggers>