以下是我真正想要做的简化示例,但我对它的问题是一样的 .
假设我有两个对象,Man和Woman,它们都具有相同的属性(Age,Height和Weight),但它们是两个不同的对象 . 我无法改变这一点 .
现在假设我有一个WPF面板,使用MVVM原理,在文本框中显示某个人的年龄 . 我使用Text =“”,其中OnePerson是视图模型中定义的Man类型的对象 .
这工作正常,但我想要一个类似的页面来显示一个女人的这个信息 . 理想情况下,我想像以前一样使用相同的视图和视图模型 . 但这很棘手,因为数据绑定指向Man-object OnePerson . 我可以通过编程方式更改数据绑定(如WPF Binding Programatically中所述),但我只能从视图's codebehind. I' m这样做,因为我们正在使用MVVM模型 .
我想让OnePerson引用一个Man或Woman对象,但我不知道这样做的好方法 . 它们是不同的类型,因此我不能仅使用if语句指定Man或Woman . 我可以将OnePerson声明为对象而不是类型,但是我不能再轻松访问Age,Height和Weight属性了 . 或者我可以创建一个完全不同的ViewModel,其中一个将OnePerson声明为Man而另一个声明为Woman,并对它们使用相同的View . 我认为这应该可行,但是对于单个视图有两个视图模型似乎有点奇怪 . 添加我自己的Person类并在它与男人或女人之间进行翻译可能只会让整个视图模型变得更复杂,当我开始添加添加新的Man / Woman或编辑现有的功能时,我可能会这样做好好复制粘贴Man视图和viewmodel,只将OnePerson对象更改为Woman .
我的问题是,在这种情况下,是否有一种干净简单的方法可以使用单个View和Viewmodel来显示男人或女人的信息 . 或者,我是否应该为这些案件打扰并制作单独的页面?
希望这很清楚 .
3 回答
我认为
ViewModel
上的问题比View或绑定更多 .View
仅仅是ViewModel
的直观表示,听起来你的问题需要在ViewModel
中修复,而不是View
.WPF 's binding system only throws a warning if a binding is invalid, and it doesn' t关心数据类型
DataContext
是 . 无论OnePerson
是Man
还是Woman
对象,您的问题({Binding OnePerson.Age}
)中显示的绑定都将正确评估,并将在该对象上显示任何Age
属性的值 .因此,最好的解决方案是使
OnePerson
属性成为Man
或Woman
的类型 . 包含所有共享属性的接口将是理想的,因为它可以通过代码访问它的属性而无需强制转换,并且您可以保留已有的所有绑定 .如果无法使用共享接口而不能使用
object
,则需要记住在引用代码中的属性之前将OnePerson
对象强制转换为Man
或Woman
类 .第二种方法是创建两个单独的属性,一个用于
Man
,另一个用于Woman
. 然后,您可以从ViewModel
轻松访问您正在使用的任何项目的属性,并且可以使用ViewModel的单个视图 .您可能需要一些标志来识别哪个是已填充的对象,并使用此标志来更新对象's properties and when you want to determine the View' s
DataContext
这是一个使用标志来确定
DataContext
的示例当然,如果您确实使用单独的
ViewModel
或想要为每种对象类型使用单独的模板,您可以使用隐式DataTemplates
之类的内容轻松完成,以确定如何绘制每个对象 .总的来说,我建议您尝试使
OnePerson
成为两个对象共享的数据类型,或者为两个对象创建单独的ViewModel
. 听起来你的类都非常相似,所以你甚至可以使用某种通用的ViewModel
,例如PersonViewModel<T>
,你传入Man
或Woman
作为T
您是否考虑过基于Interfaced对象制作对象?界面基本上创建一个 Contract ,声明从它派生的任何东西必须具有它已经声明的任何东西......派生控件可以有更多,但至少你想要的东西 . 例如 .
然后,在您的MVVM中,您可以公开的“对象”是IPersonProperties,例如
然后,无论你在MVVM对象中创建对象,都要这样做 . 你的约束力是相同的,但可能是性别 . 如果通过界面在它们之间存在某些共同点,您可以简单地引用它
但是,如果在某些方法中你需要根据特定性别做某事,你可以......
希望这为您提供实施选择的大门 .
如果你只是想为你的年龄使用一个xaml控件,你可以做到
ageusercontrol
personview