2017-08-04 37 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

相關問題