我View自己有三个物体,其中一个物体在任何时候都是可见的.在我看来,Model我有一个代表三个州的枚举.
我该如何实施ViewModel?
a)为每个对象的可见性创建一个布尔值,并将每个对象绑定到此(使用bool-> visibility转换器).
b)绑定到枚举,每个对象都有一个唯一的转换器.
c)使用带有参数的单个转换器绑定到枚举.
d)使用具有布尔关键帧的可视状态管理器,并从具有附加属性的VM驱动状态.
e)从后面的代码绑定到VM枚举,并通过代码设置可见性.
F) ?
我非常希望答案是f)(即逃避我的明显选择),因为我并不喜欢a)通过e).
欢迎和赞赏的想法.
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我想,这种情况下,如果选择不涉及业务逻辑的元素,比如可以通过按CheckBox、ToggleButton等来设置 Visibility的话,也不会违反 MVVM 的原则。