如何通过 ViewModel 更改 VisualState

发布于 2024-12-01 12:11:23 字数 599 浏览 0 评论 0原文

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

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

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

如果是,我该怎么做?

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

倾城花音 2024-12-08 12:11:23

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

设置 < code>PropertyChangedTrigger 在视图模型的“CurrentState”属性上,并添加一个 GoToStateAction< /code>更改视觉状态:

<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>

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>
寄居者 2024-12-08 12:11:23

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

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

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>

Behaviour:

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 分开。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文