【问题标题】:How to change VisualState via ViewModel [duplicate]如何通过 ViewModel 更改 VisualState [重复]
【发布时间】:2011-11-03 15:21:44
【问题描述】:

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

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

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

如果是,我该怎么做?

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

【问题讨论】:

    标签: c# wpf xaml visualstates


    【解决方案1】:

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

    在视图模型的“CurrentState”属性上设置PropertyChangedTrigger,并添加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>
    

    【讨论】:

    • 对于那些找不到 e & ei 的人,xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:ei="clr-namespace :Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
    • @ay89 谢谢,上面也加了。
    • 这些 xmlns 在 VS2015 中工作得更好:xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    【解决方案2】:

    出于多种原因,我不会在 ViewModel 中使用 VisualStateManager.GoToState,最大的原因是您必须传入要更改其视觉状态的控件。将 UI 控件传递给您的视图模型违背了整个 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 分开。

    【讨论】:

    • 你为“b”使用什么命名空间来获取 VisualStateSettingBehavior?
    猜你喜欢
    • 1970-01-01
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多