如何通过 ViewModel 控制 View VisualState



问题是:如何在 MVVM 模式(使用零视图代码隐藏(中通过我的ViewModel获取/设置ViewControl(具有两个以上的视觉状态(的VisualState

见过类似的问题,他们的答案对我不起作用:

  • 将 [VisualStateManager] 视图状态绑定到 MVVM 视图模型?
  • 如何通过视图模型更改视觉状态

注意:下面我将解释上述问题中的答案出了什么问题。如果您知道更好的方法,则可以忽略阅读此问题的其余部分。

至于第一个问题,接受的答案的方法对我不起作用。一旦我键入提到的 XAML 代码

<Window .. xmlns:local="clr-namespace:mynamespace" ..>
    <TextBox Text="{Binding Path=Name, Mode=TwoWay}"
             local:StateHelper.State="{Binding Path=State, Mode=TwoWay}" />
</Window>

它显示了一个设计时错误,上面写着:The attachable property 'State' was not found in type 'StateHelper'.,我试图通过将StateHelper.StateProperty重命名为 StateHelper.State 来克服这个问题,最终得到两个错误。1:The attachable property 'State' was not found in type 'StateHelper'.和2:The local property "State" can only be applied to types that are derived from "StateHelper".

至于第二个问题,接受的答案的方法对我不起作用。修复VisualStateSettingBehavior的语法错误后:

public class VisualStateSettingBehavior : Behavior<Control>
{
    private string sts;
    public string StateToSet
    {
        get { return sts; }
        set
        {
            sts = value;
            LoadState();
        }
    }
    void LoadState()
    {
        VisualStateManager.GoToState(AssociatedObject, sts, false);
    }
}

我在线上遇到设计时错误

    <local:VisualStateSettingBehavior StateToSet="{Binding State}"/>

那说:A 'Binding' cannot be set on the 'StateToSet' property of type 'VisualStateSettingBehavior'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.

我试图通过将VisualStateSettingBehavior.StateToSet作为依赖项属性来合并这两个解决方案,但是View中出现了其他设计时错误。

有什么建议吗?

终于,我可以解决这个问题了。解决方案类似于第一个问题的最佳答案。我发现在我的情况下,使用附加属性View.xaml有一些限制:

  1. 它必须通过 DependencyProperty.RegisterAttached 注册。
  2. 它必须是静态的
  3. 它必须有一个属性实例(getter/setter(。

我带着这种编码风格完成了它,最后的方法是:

VisualStateApplier

public class VisualStateApplier
{
    public static string GetVisualState(DependencyObject target)
    {
        return target.GetValue(VisualStateProperty) as string;
    }
    public static void SetVisualState(DependencyObject target, string value)
    {
        target.SetValue(VisualStateProperty, value);
    }
    public static readonly DependencyProperty VisualStateProperty =
        DependencyProperty.RegisterAttached("VisualState", typeof(string), typeof(VisualStateApplier), new PropertyMetadata(VisualStatePropertyChangedCallback));
    private static void VisualStatePropertyChangedCallback(DependencyObject target, DependencyPropertyChangedEventArgs args)
    {
        VisualStateManager.GoToElementState((FrameworkElement)target, args.NewValue as string, true); // <- for UIElements, OR:
        //VisualStateManager.GoToState((FrameworkElement)target, args.NewValue as string, true); // <- for Controls
    }
}

查看

<!--A property inside the object that owns the states.-->
<local:VisualStateApplier.VisualState>
    <Binding Path="State"/>
</local:VisualStateApplier.VisualState>

视图模型

private string _state;
public string State
{
    get { return _state; }
    set
    {
        _state = value;
        RaisePropertyChanged("State");
    }
}

相关内容

  • 没有找到相关文章

最新更新