在MVVM中设置可见性的最佳方法

2st*_*oke 6 wpf mvvm

View自己有三个物体,其中一个物体在任何时候都是可见的.在我看来,Model我有一个代表三个州的枚举.

我该如何实施ViewModel

a)为每个对象的可见性创建一个布尔值,并将每个对象绑定到此(使用bool-> visibility转换器).

b)绑定到枚举,每个对象都有一个唯一的转换器.

c)使用带有参数的单个转换器绑定到枚举.

d)使用具有布尔关键帧的可视状态管理器,并从具有附加属性的VM驱动状态.

e)从后面的代码绑定到VM枚举,并通过代码设置可见性.

F) ?

我非常希望答案是f)(即逃避我的明显选择),因为我并不喜欢a)通过e).

欢迎和赞赏的想法.

Ana*_*aev 3

MVVM 中的最佳方法并不一定意味着简单。我喜欢以下方法:

a) 为每个对象的可见性创建一个布尔值,并将每个对象绑定到该布尔值(使用 bool->visibility 转换器)。

此方法是设置 的 Visibility 最直观、最经典的方法Control

b) 绑定到枚举,每个对象都有一个唯一的转换器。

c) 使用带有参数的单个转换器绑定到枚举。

对于转换器来说,Enum最好不要放在Model和 旁边View。因为问题解决到了视图一侧,这是非常合乎逻辑的,并且在这里存储数据结构。原则上,这并不重要。

例子:

public sealed class InvertableBooleanToVisibilityConverter : IValueConverter
{
    enum Parameters
    {
        Normal, 
        Inverted
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var boolValue = (bool)value;
        var direction = (Parameters)Enum.Parse(typeof(Parameters), (string)parameter);

        if (direction == Parameters.Inverted)
            return !boolValue ? Visibility.Visible : Visibility.Collapsed;

        return boolValue ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return DependencyProperty.UnsetValue;
    }
}
Run Code Online (Sandbox Code Playgroud)

关于其他方法的一些评论:

d) 使用具有布尔关键帧的视觉状态管理器,并通过附加属性从 VM 驱动状态。

对于这些情况,看起来很复杂,所以看不到其中的意义。但是,如果设置 Visibility 的条件不困难,则可以使用VisualStateManager

e) 从代码隐藏绑定到 VM 枚举,并通过代码设置可见性。

当您可以使用 MVVM 的典型工具(绑定、转换器等)解决问题时,这种情况下的代码隐藏是不合理的。Visibility我想,这种情况下,如果选择不涉及业务逻辑的元素,比如可以通过按CheckBoxToggleButton等来设置 Visibility的话,也不会违反 MVVM 的原则。