2016-08-10 85 views
0

我有一個應用程序需要爲每個類的屬性顯示輸入表單。事情是,我不知道我在編譯時正在處理哪個類,所以它需要是動態的。現在,我曾經在之前做到這一點的代碼隱藏,如:使用MVVM模式創建UI元素

foreach (var P in TheType.GetProperties()){ 

    this.ControlStackPanel.Children.Add(/.../) 
// and so on 

} 

但是這一次我試圖這樣做純MVVM模式,所以我不能使用代碼隱藏。我的想法是通過構造函數將我的窗口實例注入ViewModel,但我被告知完全破壞了MVVM模式。

那麼,關於如何做到這一點的任何想法?

+0

聽起來像你正在重新發明'PropertyGrid'。但我不明白這個問題。爲什麼它必須是「動態」的? ViewModel應該**不知道任何關於視圖。 ViewModel **可以**準備一個視圖用來生成子項的列表。純MVVM - 將代碼移入行爲/轉換器/等,但請不要將其移動到ViewModel中。 – Sinatr

+0

「ViewModel可以準備一些東西將被視圖用來生成兒童的列表。」 好的,我該怎麼做?我是否準備了UIElements列表或僅列出了屬性?該視圖如何知道如何處理它?我該如何綁定到該列表? –

+0

您不準備UI元素列表。但它可以是一個ViewModels列表 - ObservableCollection ',其中'Item'包含所有必要的屬性('Icon','Text',無論你需要什麼)。該視圖可以檢查'Loaded'中的'DataContext'以獲取ViewModel實例。然後,您可以將該集合綁定到「ItemsControl.ItemsSource」,並使用數據模板或模板選擇器可視化這些(在數據模板中,您可以定義綁定到ViewModel的具體屬性)。或者,如果您不介意非純MVVM(我不這樣做),請在視圖中像您已經這樣做,但使用該集合。 – Sinatr

回答

0

創建一個視圖模型,並通過setter或property(或稍後未更改的構造函數)爲其指定對象的類型。然後將這些屬性作爲List屬性與公共getter和private setter一起發佈。您可以在屬性的getter中構建子元素,但在將類型賦予給視圖模型時,這樣做效率會更高,因此只需執行一次。然後通過XAML綁定到列表。您需要爲每種支持的類型創建一個新類。這也將幫助您瞭解輸入內容。然後在xaml一側,您需要使用模板選擇器來獲取給定類的正確形式。

這將是實現的視圖模型。

public class TheViewModel 
{ 
    public void SetTheType(Type theType) 
    { 
     Inputs.Clear(); 
     foreach (var prop in theType.GetProperties()) 
     { 
      if (prop.PropertyType == typeof(DateTime) 
      { 
       Inputs.Add(new DateTimeInput...); // create the descriptors here 
      } 
      // other known types here 
     } 
    } 

    public IList<InputBase> Inputs{get; private set;} 

} 

public class InputBase 
{ 
} 

public class DateTimeInput : InputBase 
{ 
    DateTime Value {get;set} 
} 
2

我想這樣做純MVVM模式,所以我不能使用代碼隱藏。

不,不。編號

MVVM的設計模式是關於將代碼歸入。查看代碼不屬於屬於查看模型。我已經詳細瞭解了這個here

我不知道我在編譯時處理哪個類,所以它需要動態。

在這種情況下,您可能可以使用DataTemplate爲您需要的每個類類型。請參閱documentation。這將允許您的視圖根據您處理的類類型進行動態更改。

+1

我也不明白*純MVVM *的想法(除非你正在與設計師合作,並且你的代碼會給他帶來麻煩,我猜)。將代碼放入'Window.xaml.cs'就完全沒問題。查看**可以**瞭解ViewModel。我從來沒有必須重複使用與多個ViewModel相同的View,但是如果我願意的話,一個簡單的基類/接口將解決所有問題。 – Sinatr

+0

我同意,我也從來沒有用不同的視圖模型使用相同的觀點。你很可能會*,但這不太可能。 –