2012-06-17 25 views
0

我有一個View/ViewModel,其中加載了一個ProductList。該列表在屏幕上不可見。將一個集合傳遞給viewmodel並返回一個選定的項目

我需要做的是顯示一個新的View/ViewModel(例如SelectProductView/SelectProductViewModel),將ProductList傳遞給它們,並且在用戶選擇特定產品後關閉此視圖並使用選定的產品。

達到此目的的最佳方法是什麼?

我正在使用MVVMLight,但我想這個想法不應該僅限於它。 最簡單的方法是創建一個視圖,並將集合傳遞給它,但這聽起來不像MVVM友好。我正在考慮從第一個ViewModel創建SelectProductViewModel並將其傳遞給它,但我不知道如何自動創建SelectProductView並將其綁定到創建的SelectProductViewModel。

編輯:在我的應用程序視圖結構有點複雜。我有一個主視圖,基本上需要託管一個SelectProductView,因爲此視圖必須覆蓋整個屏幕。 MainView包含許多子孫視圖(通過選項卡),因此可能會有3個不同的子視圖或grand childView可能發出請求來選擇產品。另外,某些視圖不會預裝產品,因此應將此任務傳播到SelectProductViewModel。結構

例子:

       MainView 
         /     \ 
     ChildViewA         ChildViewB 
      /\          / \ 
GrandChildViewA1 GrandChildViewA2   GrandChildViewB1 GrandChildViewB2 

所以,GrandChildViewA1,ChildViewB和GrandChildViewB2可以發出對產品的要求進行選擇。只有發出請求的觀點才能獲得所選產品,而其他人則不應該爲此而煩惱。 GrandChildViewA1將在其中加載產品,但GrandChildViewB2不會在其中加載ProductList。這意味着,出於性能考慮,GrandChildViewA1應將產品列表傳遞給SelectProductViewModel,而GrandCHildViewB2不會在其中包含Product列表,因此SelectProductViewModel應該從數據庫中獲取數據。

回答

0

我會創建一個通用的viewModel,它定義了接收數據的合同。

public abstract class PassDataViewModel<T> : ObservableObject 
{ 
    public T Data { get; } 
} 

然後我會創造一個更一般的視圖模型爲您的產品列表,像這樣:

  1. 你的第一個視圖模型可以創建一個:

    public class SelectProductViewModel : PassDataViewModel<Product> 
    { 
        private Product _selectedProduct; 
        private ObservableCollection<Product> _products = new ObservableCollection<Product>(); 
    
        public SelectProductViewModel(IList<Product> products) 
        { 
         _selectedProduct = _products.First(); 
        } 
    
        public IEnumerable<Product> Products 
        { 
         get { return _products; } 
        } 
    
        public Product SelectedProduct 
        { 
         get { return _selectedProduct; } 
         set 
         { 
          _selectedProduct = value; 
          OnPropertyChanged("SelectedProduct"); 
          OnPropertyChanged("Data"); 
         } 
        } 
    
        public Product Data 
        { 
         get { return _selectedProduct; } 
        } 
    } 
    

    你可能會以如下方式使用例如SelectProductViewModel(例如,當調用一個命令時)

  2. 您將您的產品列表傳遞到新的SelectProductViewModel實例。
  3. 使用DataTemplate來更改屏幕上的視圖(this後會告訴你如何做到這一點)。
  4. 在父viewModel中有一個屬性,它返回SelectProductViewModel的data屬性返回的產品(您將需要將PropertyChanged事件傳播給父視圖模型)。
+0

本傑明您好,我有幾個問題:1)爲什麼我需要數據和SelectedProduct屬性? 2)我編輯了一個問題以提供更多信息,那麼您能否詳細說明如何實例化SelectProductViewModel以及如何通知感興趣的視圖選擇特定產品? – Goran

+0

1)你沒有。你可以擺脫通用的ViewModel,並使用SelectProductViewModel。我使用通用ViewModel的唯一原因是,父ViewModel不必知道SelectProductViewModel的具體實現細節,儘管我承認在完成解耦之前需要做更多的工作。這個想法是爲有興趣在選擇「數據」時被通知的各方簽訂合同。 2)你如何/在哪裏實例化ViewModel取決於你。 –

+0

問題不僅在於如何實例化視圖模型,而是關於實例化,等待完成其工作,關閉和獲取結果的整個過程。在你的例子中。如何調用「first ViewModel」,知道獲取Data屬性的值? – Goran

0

最簡單的方法是先去viewmodel的第一個方法,然後使用dialogservice來顯示選擇視圖。

您使用ProductionList的viewmodel只需調用dialogservice並將ProductSelectionViewmodel與ProductionList作爲參數。因爲這是視圖模型首先你必須創建一個數據模板,所以WPF知道如何渲染你的ProductSelectionViewmodel。

here是一個簡單對話服務的鏈接。

btw:在我看來,viewmodel的第一種方法在做mvvm時要容易得多。

編輯:

在ProductionListViewModel

在SelectProductCommand

var selectProductViewModel = new SelectProductViewModel(this.ProductionList); 
var result = this.uiDialogService.ShowDialog("Select Product", selectProductViewModel); 

//if result true, simple get the selected product 
this.SelectedProduct = selectProductViewModel.MySelectedProduct; 

多數民衆贊成 - 簡單和容易

+0

嗨,我是今天通過你的例子在你已經鏈接的線程上,看起來你是從ViewModel調用UI視圖(WindowDialog)? ViewModel不應該知道任何有關Views的主規則,並且不應該直接實例化它們嗎? – Goran

相關問題