我最近一直在学习 WPF 中的 MVVM 模式,并且刚刚开始制作我的第一个适当的、相当大的应用程序。到目前为止一切都很顺利,我很喜欢我所看到的。然而,我最近遇到了一些绊脚石。
该应用程序是使用主 TabControl
构建的, 每个 TabItem
包含一个相当大的细节 View 。
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
的 SelectedItem
绑定(bind)到 MainViewModel.ActiveTab
.
到目前为止一切顺利!但是,我不确定我得到的是如何在遵循 MVVM 的同时处理选项卡的关闭。如果我不想严格遵守 MVVM(为了正确学习它),我会绑定(bind)一个 MouseDown
。 -TabItem
上的事件-headers 并因此获得对该事件中单击项目的引用,将其从 OpenTabs
中删除以这种方式收藏。但是 - 除非我弄错了 - 交互逻辑不应该需要引用实际的 UI 项目才能有效和适当的 MVVM。
那么,我该如何处理这种 MVVM 风格呢?我是否使用将特定参数发送到我的 MainViewModel
的命令? ?这似乎是 ICommand
的首选实现在 MVVM 中不采用对象参数(查看 MVVM Light 以及其他一些教程)。
我应该只创建一个 CloseTab(int id)
吗?我的公共(public)方法 MainViewModel
并在捕获 Click
后从 View 代码隐藏中调用它在我的 TabItem
关闭按钮?这看起来像是 MVVM 作弊。 :)
还有最后一点 - 即使我在 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}">
注意:您的绑定(bind)路径当然可能会有所不同,具体取决于您的 View 和 View 模型的设置方式。
最佳答案
最好和正确的方法是创建命令。在不同的框架中 ICommand
通常有两个实现,带参数和不带参数(通常你不需要它)。
MVVM light有两个ICommand
实现以及: RelayCommand
和 RelayCommand<T>
关于c# - 获取对 View 中单击项的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11097791/