【问题标题】:How to control View VisualState through ViewModel如何通过 ViewModel 控制 View VisualState
【发布时间】:2015-09-27 19:17:33
【问题描述】:

问题是:如何通过我的ViewModel MVVM 模式(零视图代码隐藏)?

我看到过类似问题的答案对我不起作用:

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

至于第一个问题,accepted answer 的方法对我不起作用。一旦我输入提到的 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".

至于第二个问题,accepted answer 的方法对我不起作用。修复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 中遇到了其他设计时错误。

有什么建议吗?

【问题讨论】:

    标签: c# wpf xaml mvvm viewmodel


    【解决方案1】:

    终于,我可以解决这个问题了。该解决方案类似于first question's best answer。我发现在我的情况下,View.xaml 使用附加属性有一些限制:

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

    我以this 编码风格解决了这个问题,最后的方法是:

    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");
        }
    }
    

    【讨论】:

    • 我猜VisualStateApplier应该继承DependencyObject吧?
    猜你喜欢
    • 2011-11-03
    • 2015-07-21
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-04
    • 2021-10-21
    相关资源
    最近更新 更多