【发布时间】:2015-06-18 07:13:21
【问题描述】:
在不破坏 MVVM 的情况下,有没有办法在用户控件中公开子控件的某些属性,以便窗口或其他使用它的用户控件可以直接访问这些属性?
例如,我有一个用户控件,它有一个设置了网格视图列、标题的列表视图,并绑定到一个视图模型。但是用户控件中的列表视图已经选择了项目属性,因此我想向主机公开,而不必执行 usercontrol.customListView.property 之类的操作。还是我应该这样做?我想只使用 usercontrol.property,省略 customListView。也许我应该只在返回列表视图控件属性的用户控件代码中创建属性,我希望这些属性直接附加到用户控件?
我觉得后一种选择并没有真正破坏 MVVM,因为它们暴露给主机进行交互,与视图本身没有真正的关系。任何建议将不胜感激。
编辑:事实上,我真的很想在用户控件上直接有一个 SelectedItem 属性,它不是 ListViewItem 或对象,但实际上包含的数据类型是这样的:
public MyDataType SelectedItem {
get {
return customListView.SelectedItem as MyDataType;
}
}
这在 MVVM 中是否允许?因为我看不到如何在 ViewModel 中拥有它,所以它似乎必须在后面的部分类代码中。
【问题讨论】:
-
只需在您的控件上添加 DepandencyProperty 并在子控件上绑定/重新绑定它 (
Binding RelativeSource{FindAncestor})(顺便说一句,也许 OT,WPF 数据网格上的 .columns 不可绑定)。看不到 MVVM 的任何问题 - 可以说 ComboBox 正在使用其他控件,而您在 MVVM 中使用它没有任何问题:) -
这个问题与MVVM无关。
-
"我有一个用户控件,它有一个设置了 gridviewcolumns、标题的列表视图,并绑定到一个视图模型。" 是的,这就是你遇到问题的原因.您的 UserControl 中不应该有任何 ViewModel。您应该在表面上公开您需要的所有属性,然后将您的 UC 子控件绑定到这些属性。如果您必须在 UC 中执行 UI 逻辑,请使用代码隐藏。不要创建设计为在 UC 内部使用的 VM。 TextBox 有 TextBoxViewModel 吗?不。将您的 UC 视为控件,而不是逻辑的子集。
-
@Sheridan 你读过这个问题了吗?我正在使用 MVVM 并希望在用户控件上公开一些内容。我不知道这是否会影响它的 MVVM 方面,或者我们是否应该在实践中避免这种情况,但我只是不知道如何推迟对视图模型的暴露。
-
是的,我读过这个问题。你的设计对你不利。从您的第二次澄清来看,如果您的 UC 包含另一个不同的过程,它似乎太大了。如果 UC 很小,则最有效,设计为针对整体 MVVM 设计的一部分而设计的专用控件(如 TextBox 编辑字符串,PersonUserControl 可能编辑 Person 模型)。如果您使用 UC 来包含大量 UI,您会发现自己处于上述评论中描述的情况。