2017-08-04 44 views
0

在MVVM场景中,View负责显示ViewModel。这对ViewModel无关紧要。应该使用MVVM将图像路径存储在VM中

现在我想用图像(例如类似trafficlight的图标)显示某些属性(例如状态)的值。

我发现的大多数例子都将路径存储到ViewModel属性中不同版本的图标。并根据状态进行更改。然后在视图中将来自图像源的绑定应用于所述属性。

这感觉不对。 ViewModel不应该知道属性的渲染类型。至于ViewModel知道它可以呈现为任何东西(标签,测试,图像,颜色等)。

将ViewModel属性显示为图像/图标的正确MVVM-WPF方法是什么?因此,不将图像路径/ URL存储在ViewModel中。

+0

您可以拥有一个属性,该属性包含适当图像的(相对或绝对)路径,并将元素的图像源绑定到该图像源。这种方式VM处理数据,而不是数据类型。 – Dido

+0

由于VM仍然负责选择图像。它认为它不应该在乎如何显示财产(无论是图像还是标签或...),因此不应该提供图像路径。 – Dribbel

+0

这取决于你如何看待每一层的责任。我通常将核心领域逻辑放入我的模型中,因为我不喜欢贫血领域模型,但将业务逻辑放入视图模型或服务中,这取决于项目的复杂性。将显示什么图标与业务逻辑有关。因此它属于VM。如果你不想在你的虚拟机中拥有Uri属性,把它们替换成你想要的任何东西,然后编写一个转换器在该图标和Uri之间转换。 – Dido

回答

2

正确的做法是使用转换器。例如,要将状态值转换为图标,请在虚拟机中使用枚举并将转换器用于图标路径。

在我们的模型

所以......

public enum ResultType { Unknown, Good, Bad, Suspect }; 
    public ResultType Type { get; set; } 

然后转换

public class ResultTypeIconConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value is Result.ResultType) 
     { 
      return GetIconPath((Result.ResultType)value); 
     } 
     return "Images/glyphicons-195-question-sign.png"; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
    public static string GetIconPath(Result.ResultType rt) 
    { 
     switch (rt) 
     { 
      case Result.ResultType.Bad: 
       return "pack://application:,,,/someassembly;component/Images/badresult.png"; 
      case Result.ResultType.Good: 
       return "pack://application:,,,/someassembly.WPF;component/Images/goodresult.png"; 
      case Result.ResultType.Suspect: 
       return "pack://application:,,,/someassembly.WPF;component/Images/suspectresult.png"; 
      case Result.ResultType.Unknown: 
       return "pack://application:,,,/someassembly.WPF;component/Images/unknownresult.png"; 
      default: 
       return "pack://application:,,,/PetroUtilitiesUI.WPF;component/Images/glyphicons-195-question-sign.png"; 
     } 
    } 
} 

XAML资源

<local:ResultTypeIconConverter x:Key="IconConverter"/> 

XAML参考

<Image Height="15" Width="15" Source="{Binding Type, Converter={StaticResource IconConverter}}" DockPanel.Dock="Left"/> 

所以这是非常干净的。该模型并不知道任何关于图标的知识,而且该视图并不知道关于枚举的任何信息。现在...是VM还是视图的类型转换器部分?我把这个问题留给了哲学家。

+0

另一种“正确的方式”将是一组DataTrigger,而不是绑定转换器。 – Clemens

+1

@Clemens - 说实话,我认为DataTriggers在这里几乎总是正确的方式,因为它将我们正在处理的视觉关注放在XAML文件中,这是该文件所属的位置。使用Blend的专用UX设计师会在哪里放置它?不在C#代码.... – hoodaticus

相关问题