2012-06-19 25 views
4

我最近一直在WPF中學習MVVM模式,並開始製作我的第一個適當的,相當大的應用程序。到目前爲止,這一切都很順利,我喜歡我所看到的很多。不過,我最近遇到了一些絆腳石。獲取有關點擊項目的參考

該應用程序的主要內容是TabControl,每個TabItem都包含相當大的詳細信息視圖。

TabControl inside main View, ItemsSource bound to MainViewModel.OpenTabs 
TabItem with data specific View+ViewModel 
TabItem with data specific View+ViewModel 
TabItem with data specific View+ViewModel 
etc... 

OpenTabs集合是MainViewModel一個ObservableCollection<BaseViewModel>,並且TabControlSelectedItem勢必MainViewModel.ActiveTab

到目前爲止好!然而,我不知道我得到的是如何處理關閉標籤,同時遵循MVVM。如果我沒有試圖嚴格控制MVVM(爲了正確地學習它),我只需要綁定一個MouseDown -event,然後在這個事件中獲得對被點擊項的引用,將它移除以這種方式從OpenTabs收藏。但是 - 除非我錯了 - 交互邏輯不應該需要引用實際的UI項目才能成爲有效且適當的MVVM。

那麼,我該如何處理這種MVVM風格呢?我是否使用將特定參數發送到我的MainViewModel的命令? MVVM中的ICommand的首選實現似乎不採用對象參數(查看MVVM Light以及其他一些教程)。

如果我只是在我的MainViewModel創建CloseTab(int id)公共方法和追趕我的TabItem關閉按鈕Click後調用從視圖代碼隱藏?這似乎是MVVM欺騙。 :)

還有一個最後的注意事項 - 即使我點擊關閉不是當前活動的TabItem也應該工作。否則,使用OpenTabs.Remove(ActiveTab)不會很難。

感謝您的幫助!我也很感激任何鏈接推薦閱讀/觀看這些問題。

解決方案:看來最好的方法是使用一個可以接受命令參數的命令。我使用MVVM輕型框架RelayCommand:

在MainViewModel:

CloseTabCommand = new RelayCommand<BaseViewModel>((vm) => 
{ 
    OpenTabs.Remove(vm); 
}); 

在XAML:

<Button 
Command="{Binding Source={StaticResource MainViewModel}, Path=CloseTabCommand}" 
CommandParameter="{Binding}"> 

注意:您的結合路徑當然可以取決於你的意見和的ViewModels如何建立。

+1

這取決於您真正使用的MVVM框架。總體思路是虛擬機有一個'ICommand',可以使所有綁定的視圖「消失」,但是這裏有很多選項。例如,該命令可能會導致事件發生;視圖可以訂閱該事件並從邏輯樹中移除。 – Jon

回答

3

最好的和正確的方法是創建命令。在不同的框架ICommand通常有兩個實現,與參數和沒有一個(往往你不需要它)。

MVVM光有兩個ICommand實施以及:RelayCommandRelayCommand<T>

+0

啊 - 我們有。這使得它更容易。我不知道RelayCommand的通用命令參數版本。 –

2

我建議創建自己的DelegateCommand實現,如何這可以發現herehere一個很好的例子。或者使用Prism variant,你可以下載它here

使用DelegateCommand可以將參數傳遞給ViewModel。

+0

感謝您的回覆。看起來這是首選的方式,我根本沒有注意到我的框架中的RelayCommand 。 –