我最近一直在学习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
集合在ObservableCollection<BaseViewModel>
上是MainViewModel
,而TabControl
的{{1}}绑定到SelectedItem
。
到目前为止一切顺利!但是,我不确定我得到的是如何在MVVM之后同时处理选项卡的关闭。如果我没有试图严格要求MVVM(为了正确学习它),我只需在MainViewModel.ActiveTab
- 标题上绑定一个MouseDown
- 事件,从而得到对它的引用单击该事件中的项目,以这种方式将其从TabItem
集合中删除。但是 - 除非我弄错了 - 交互逻辑不应该需要引用实际的UI项目才能成为有效且适当的MVVM。
那么,我该如何处理这种MVVM风格呢?我是否使用将特定参数发送到OpenTabs
的命令?似乎MVVM中MainViewModel
的首选实现不接受对象参数(查看MVVM Light以及其他一些教程)。
我应该在ICommand
上创建一个CloseTab(int id)
公开方法,并在我的MainViewModel
关闭按钮上抓取Click
之后从视图代码隐藏中调用该方法吗?这似乎是MVVM作弊。 :)
也是最后一个注释 - 即使我点击不是当前活动的TabItem
上的关闭,这也应该有效。否则,使用TabItem
进行设置并不困难。
感谢您的帮助!我也很欣赏有关这些问题的推荐阅读/观看的任何链接。
解决方案:似乎最好的方法是使用可以接受命令参数的命令。我使用了MVVM Light框架中的RelayCommand:
在MainViewModel中:
OpenTabs.Remove(ActiveTab)
在XAML中:
CloseTabCommand = new RelayCommand<BaseViewModel>((vm) =>
{
OpenTabs.Remove(vm);
});
注意:您的绑定路径当然可能会因视图和ViewModel的设置方式而异。
答案 0 :(得分:3)
最好和最正确的方法是创建命令。在不同的框架中ICommand
通常有两个实现,带参数但没有一个(通常你不需要它)。
MVVM指示灯还有两个ICommand
实现:RelayCommand
和RelayCommand<T>
答案 1 :(得分:2)