2016-07-13 144 views
2

來自WPF/MVVM專家的一些建議,請參考。WPF/MVVM - 綁定子控件集合

我來自Windows窗體背景,我將一個個人項目從VB.NET移植到WPF。我開始直接重寫代碼隱藏文件中的邏輯,雖然有一個離散的數據訪問層。但是後來我發現MVVM,並且我「做得不對」,應該將邏輯抽象爲查看模型訪問數據模型。我想我已經吸收了新的範例,我的代碼背後的代碼現在(幾乎)是空的。 (另外,我購買了MVVM背後的基本原理,但由於所有路由事件和命令的「管道」等原因,我不確定'更易於測試和調試'的論點,我欣賞但我認爲有時需要模糊而不是澄清發生了什麼,但我是一個非常新手,也許會來練習。)

無論如何 - 這是什麼讓我撓了撓頭;該應用程序是潛水中心的潛水計劃/錄製工具。從邏輯上講,它就像日曆或日記應用程序一樣,需要記錄每次潛水的時間和地點以及每次潛水的人員。主屏幕類似於日記的一頁,我有一個封裝了潛水信息的用戶控件。在更改選定日期後,日記頁面將被清除並重新填充新選定日期的潛水。查看模型檢索並公開新日期的「潛水」對象(類)列表。容器是一個Stackpanel,我想清除它的子項,然後創建新的Dive用戶控件並將其添加到子控件集合中。

我的問題是 - 哪裏是適當的地方做到這一點 - 查看代碼背後或查看模型?前者是相對容易的,但在我看來打破了這種模式,但我很難以在視圖模型中實現它。序列需要是

  • 用戶選擇新的日期(日曆控制)
  • 處理所選擇的日期改變事件
  • 清除的StackPanel子控件
  • 從數據庫取回潛水爲新的日期的列表,並生成每個用戶控件
  • 將用戶控件添加爲堆棧面板子控件。

我猜我在問什麼 - 是否有一種方法將子控件的集合綁定到視圖模型中的對象集合,使其動態響應 - 這是一個明智的方法嗎?

+0

你在底部列表是100個%WinForms和0%MVVM。在嘗試重寫之前,您可能想要創建一對原型,在其中進行非常簡單的MVVM工作,作爲學習如何完成不同任務的一種方式。如果您不明白mvvm如何在wpf中工作,請勿嘗試在生產代碼中學習它。 – Will

+0

謝謝Will,我確實承認我是MVVM新手,並且我已經開發了一些'玩具'應用程序。仍然讓我的頭繞着綁定的力量.. –

+0

更多的玩具應用程序!我救了我所有的。有數百個不同的科目。這是學習的好方法。 – Will

回答

1

執行此操作的適當方法是將StackPanel包裝在ItemsControl中,並將ItemsSource綁定到選定日期的Dives。當您的DivesOfThatDay更改(確保實現INotifyChanged或DependencyProperty,或使用ObservableCollection)時,將自動生成每個條目。

<ItemsControl ItemsSource="{Binding DivesOfThatDay}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel Orientation="Vertical"/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate DataType="{x:Type Dive}"> 
      <!-- Your Template --> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

在MVVM中,您應該始終避免在代碼隱藏中生成控件。您的視圖應該從您的ViewModel中獲取數據並自行完成 - 否則MVVM將會毫無用處。在你的情況下,它應該像這樣工作:

  1. 用戶選擇視圖
  2. 一個新的日期,因爲在視圖日期控件綁定到一些財產在你視圖模型,該屬性得到更新。
  3. viewmodel通過清除當前的潛水集合並獲取新潛水來對此更改作出反應。
  4. (從數據庫)的模型數據被封裝在一個視圖模型(一個Dive)並添加到潛水集合中的視圖模型
  5. 視圖ItemsControl)得到通知這種變化的(通過INotifyPropertyChangedINotifyCollectionChanged或其他)並告訴其ItemContainerGenerator更新控件。
  6. 的ItemsContainerGenerator在視圖模型生成每一個Dive視圖把它添加到StackPanel中。

或簡稱V→VM→M→VM→V

+1

我建議他讓'Dives'成爲'ObservableCollection',在新的集合實例上提升'PropertyChanged',而不用介意其他方法。不能因此而出錯。 –

+0

@EdPlunkett *「不能」*可能有點誇張。我見過很多使用'dataThatDoesntUpdate = new ObservableCollection ...'的人,並且想知道他們做錯了什麼。但我同意 - 一個'ObservableCollection'或任何其他實現'INotifyCollectionChanged'的類將很好地適應這種情況。他的基本方法'從數據庫檢索新日期的潛水列表併爲每個數據生成用戶控件'絕對不應該手動完成。 –

+0

沒錯,沒有什麼東西不能做錯了。完全同意有關創建控件的ItemsControl + DataTemplate。 –