【问题标题】:WPF MVVM dilemma - Where to put the command that acts on collection item?WPF MVVM 困境 - 将作用于集合项的命令放在哪里?
【发布时间】:2020-11-18 13:56:00
【问题描述】:

假设我有一个包含ItemModel 集合的MasterViewModel。如果我想将新的ItemModel 添加到我的收藏中,我会将AddItemCommand 放入那个MasterViewModel。现在,如果我想在每个项目旁边显示一个删除按钮,我应该把这个命令放在哪里?肯定不在ItemModel?!

我是否需要创建ItemModel 的几乎相同的副本,例如ItemViewModel?这听起来像是很多支撑工作,但即便如此我也不确定该命令如何能够从集合中删除 ItemModel

最明显的做法似乎是MasterViewModel中的AddItemCommandRemoveItemCommand,但是这种情况下怎么做数据绑定呢?控件的 DataContext 已切换到一个集合,因此我不再能够从单个项目级别看到该命令。我看到了一个绑定技巧,它找到了祖先的 DataContext,但至少可以这么说,它看起来很老套或不直观。这是首选解决方案还是有更好的方法?

【问题讨论】:

  • ViewModel 用于视图和模型之间的命令和其他绑定工作...模型是业务逻辑。所以是的,你也需要一个 ItemViewModel
  • 这两个命令都应该在托管命令应该操作的集合的视图模型中实现。您不应将集合设置为 DataContext。视图模型应该是 DataContext。您只需通过调整Binding.Path 绑定到此视图模型的集合/属性。如果您需要帮助来修复您的 DataContext,您应该发布您当前的相关代码。关于删除命令:这实际上取决于您使用的数据视图。 DataGrid 已经公开了一个删除命令,这将为您节省一些工作。
  • 通常你必须将SelectedItem绑定到视图模型。当单击一个项目或该项目内的删除按钮等控件时,您会自动选择该项目。删除命令只需从源集合中删除SelectedItem。你真的应该发布相关代码。
  • 谢谢@BionicCode。我的偏好是使用 CommandParameter="{Binding}" 而不是 SelectedItem 属性
  • 使用 SelectedItem 是错误的,因为您希望能够删除任何项目而不必选择它。

标签: wpf mvvm binding


【解决方案1】:

AddItemCommand 绝对属于MasterViewModel,因为它不能是对单个项目的操作。

RemoveItemCommand 也属于MasterViewModel,因为它将更新项目列表。但是,绑定不遵循基本方法。

  1. 假设触发命令的按钮是项目模板的一部分,那么您必须使用相对绑定来定位命令(这就是您所说的“hacky”吗?)

Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.RemoveItemCommand}"

  1. 您必须告诉命令要删除哪个项目

CommandParameter="{Binding}"

并在与您的命令对应的方法中使用此参数。

【讨论】:

  • 我在写同样的东西。应得的分数。
  • 是的,这就是我所指的绑定。也许我应该说不直观,而不是hacky,但我会认为这是这样做的正确方法。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-02
  • 2017-08-02
  • 2015-01-17
  • 1970-01-01
相关资源
最近更新 更多