获取对视图中单击项的引用

时间:2012-06-19 09:05:30

标签: c# wpf mvvm

我最近一直在学习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的设置方式而异。

2 个答案:

答案 0 :(得分:3)

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

MVVM指示灯还有两个ICommand实现:RelayCommandRelayCommand<T>

答案 1 :(得分:2)

我建议您创建自己的DelegateCommand实施,这是一个很好的示例,说明如何找到herehere。或者使用Prism variant,您可以下载它here

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