2015-09-18 78 views
1

我們已經爲我們的WPF應用程序提供了一個現有的UI,其中單獨的按鈕按下時會顯示基於綁定到可見性(MVVM)的元素,其中ICommand會將這些可見性屬性設置爲開或關。這些工作很好,但最近我們被要求按按鈕來顯示/隱藏像以前一樣的元素,但另一種類型的按鈕按下來顯示一些其他元素,但在一個TabControl中。ViewModel中的UIElement的UserControl會打破MVVM?

我想這樣做是的方式:

a)創建包含這取決於按鈕按下這些用戶控件通過視圖模型實例化這些元素

B)在運行時間期間單獨用戶控件,並結合到在查看的ItemsSource通過一個ObservableCollection:

視圖模型:

private ObservableCollection<Object> centerView; 
public ObservableCollection<Object> CenterView 
{ 
    get { return centerView; } 

}    

...

UserControlOfReportRelatedElements reportsView = new UserControlOfReportRelatedElements(); 
    CenterView.Clear(); 
    Grid.SetRow(reportsView, 0); 
    CenterView.Add(reportsView); 

XAML:

<ItemsControl ItemsSource="{Binding CenterView}" Grid.Row="2"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <Grid/> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
    </ItemsControl> 

所以取決於用戶控件是否被包裹在一個TabControl,我們將簡單地滑它在的ObservableCollection(運行時)。

這個工程,它很方便。但是這會打破MVVM嗎?還有什麼我們可以做的嗎?

回答

3

我會說,是的,打破了MVVM模式。 MVVM的其中一個思想是保持View(UI)和ViewModel(商業邏輯)彼此分離。

您的解決方案可能是創建一個Base-ViewModel-Class,其中繼承了不同視圖(您的選項卡頁)的ViewModels。在你的ObserableCollection中你有你的Base-ViewModel-Instanced。

要顯示你的ViewModels正確的意見,你可以這樣做在你的App.xaml

<DataTemplate DataType="{x:Type viewModel:CustomViewModel1}"> 
    <view:CustomView1/> 
</DataTemplate> 

下面通過這個定義,你告訴你的應用程序,每當CustomViewModel1應顯示的CustomView1應顯示。通過這個DataContext也被設置。

一個非常好的例子是this

3

是的,在視圖模型具有UI元素的引用打破MVVM。視圖模型應該是完全孤立的,不知道視圖。

解決此問題的一種方法是將實際數據內容作爲視圖模型的屬性公開。然後,您可以使用各種機制來顯示基於該內容的控件。例如,如果您公開對象列表,則可以使用數據模板根據對象的類型顯示不同的控件。

因此,您只需在視圖模型上公開數據,並期望視圖提供正確顯示該數據的必要手段。

例如,如果不暴露UserControlOfReportRelatedElements控件,則會暴露包含數據的ReportData對象。然後,您將在ReportData類型上註冊一個數據模板,然後顯示UserControlOfReportRelatedElements元素並顯示來自ReportData對象的數據。

+0

ContentControl旨在支持問題正在討論的情況,當與您在答案中提到的技術結合使用時。 – user3690202

+0

我從這個答案中學到了很多東西,但是我與TomTom一起工作,因爲在這一點上實現起來要容易得多。謝謝你。我會這樣想下去 – Tyress

+0

@Tayress我實際上認爲我們都指的是同一件事;) – poke

相關問題