我最近一直在学习 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
,而' TabControl
sSelectedItem
是必然的MainViewModel.ActiveTab
。
到现在为止还挺好!但是,我不确定我得到的是如何在遵循 MVVM 的同时处理选项卡的关闭。如果我不想对 MVVM 严格要求(为了正确学习它),我只需在MouseDown
-headers 上绑定一个 -event TabItem
,从而在该事件中获取对单击项目的引用,将其从OpenTabs
以这种方式收集。但是 - 除非我弄错了 - 交互逻辑不应该需要对实际 UI 项目的引用才能有效和正确的 MVVM。
那么,我该如何处理这种 MVVM 风格呢?我是否使用将特定参数发送到我的命令MainViewModel
?似乎ICommand
MVVM 中的首选实现不采用对象参数(查看 MVVM Light 以及其他一些教程)。
我是否应该在我的关闭按钮上创建一个CloseTab(int id)
公共方法MainViewModel
并从视图代码隐藏中调用它?这似乎是 MVVM 作弊。:)Click
TabItem
最后一点 - 即使我单击关闭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}">
注意:您的绑定路径当然可能会根据您的视图和视图模型的设置方式而有所不同。