4

我最近一直在学习 WPF 中的 MVVM 模式,并且刚刚开始制作我的第一个合适的、相当大的应用程序。到目前为止,一切都很顺利,我很喜欢我所看到的。然而,我最近遇到了一个绊脚石。

该应用程序是使用 main 构建的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集合是ObservableCollection<BaseViewModel>on MainViewModel,而' TabControlsSelectedItem是必然的MainViewModel.ActiveTab

到现在为止还挺好!但是,我不确定我得到的是如何在遵循 MVVM 的同时处理选项卡的关闭。如果我不想对 MVVM 严格要求(为了正确学习它),我只需在MouseDown-headers 上绑定一个 -event TabItem,从而在该事件中获取对单击项目的引用,将其从OpenTabs以这种方式收集。但是 - 除非我弄错了 - 交互逻辑不应该需要对实际 UI 项目的引用才能有效和正确的 MVVM。

那么,我该如何处理这种 MVVM 风格呢?我是否使用将特定参数发送到我的命令MainViewModel?似乎ICommandMVVM 中的首选实现不采用对象参数(查看 MVVM Light 以及其他一些教程)。

我是否应该在我的关闭按钮上创建一个CloseTab(int id)公共方法MainViewModel并从视图代码隐藏中调用它?这似乎是 MVVM 作弊。:)ClickTabItem

最后一点 - 即使我单击关闭TabItem不是当前活动的,这也应该有效。否则设置起来不难OpenTabs.Remove(ActiveTab)

谢谢你的帮助!我也很感激有关这些问题的推荐阅读/观看的任何链接。

解决方案:似乎最好的方法是使用可以接受命令参数的命令。我使用了 MVVM Light 框架中的 RelayCommand:

在 MainViewModel 中:

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

在 XAML 中:

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

注意:您的绑定路径当然可能会根据您的视图和视图模型的设置方式而有所不同。

4

2 回答 2

3

最好和正确的方法是创建命令。在不同的框架ICommand中通常有两种实现,带参数和不带参数(通常你不需要它)。

MVVM light 也有两个ICommand实现:RelayCommandRelayCommand<T>

于 2012-06-19T09:10:01.923 回答
2

我建议创建你自己的DelegateCommand实现,一个很好的例子可以在这里这里找到。或者使用 Prism变体,您可以在此处下载。

使用 DelegateCommand,您可以将参数传递给您的 ViewModel。

于 2012-06-19T09:11:55.820 回答