如何将与DataView一起使用的DataTemplate与GridView一起使用?
在回答之前:这个问题是关于WPF的ListView
控件(使用GridView
)。 它不是关于WPF的DataGrid
控件,ASP.NET的DataGrid
或ListView
控件,或WinForm的DataGridView
或ListView
控件。 它们听起来非常相似并且经常混淆,但错误控制类型的答案对我来说无益,更重要的是浪费了你写答案的时间,我认为不应该浪费。
我有一个带有GridView
的ListView
控件,它有几个绑定到我的视图模型属性的列。 我可以通过指定CellTemplate
(内联或通过资源)轻松自定义GridViewColumn
单元格的可视外观。
现在我的视图模型上有一个特定的属性; 它的类型是一个抽象基类,它的值可以是几种派生类型之一。 每个派生类型应在单元格中具有不同的DataTemplate
。 幸运的是, GridViewColumn
有一个CellTemplateSelector
,它完全符合我的要求,但需要编写一些管道代码。 但是看一下DataTemplateSelector
的页面,它说:
请注意,如果您有不同类型的对象,则可以在DataTemplate上设置DataType属性。 如果这样做,则无需创建DataTemplateSelector。 […]有关更多信息,请参阅数据模板概述 。
欢呼! 无需编写管道代码。 我的类型不同,所以这似乎是一个完美的契合。 但是,即使我定义了一个DataTemplate
,其DataType
与其中一个DataTemplate
绑定列(使用GridViewColumn
的DisplayMemberBinding
绑定)的特定派生类型相匹配,它也没有效果。
我只想根据GridView
某个列的运行时类型显示不同的DataTemplate
。 DataType
-targeted DataTemplates
是否与GridView
不兼容? 有没有办法使用它们,还是我必须使用指定CellTemplateSelector
? 也许有一种方法可以在GridViewColumn
的CellTemplate
指定多个DataTemplate
,这样DataType
属性就会产生影响?
WPF允许您在逻辑树中插入ViewModels
等对象,而DataTemplate
可用于告诉WPF在绘制Visual Tree时如何绘制指定的对象。
隐式DataTemplate
是一个只定义了DataType
的DataTemplate
(无x:Key
),只要WPF尝试在VisualTree中呈现指定类型的对象,它就会自动使用。
所以,你可以使用
告诉WPF使用ViewA绘制ViewModelA,使用ViewB绘制ViewModelB,使用ViewC绘制ViewModelC。
如果你只想将它应用到你的GridView而不是整个Window,你可以指定
(或
,我不记得哪一个)
应该注意的是,如果使用DisplayMemberBinding
绑定列,它将呈现为TextBox
,其Text
值绑定到您的属性,这意味着它将呈现YourViewModel.ToString()
而不是尝试在VisualTree中绘制ViewModel使用您的DataTemplate
。
为了避免这种情况,只需将CellTemplate
设置为ContentPresenter
,其Content
属性绑定到ViewModel
,它将使用隐式DataTemplates
呈现ViewModel。
DisplayMember*
属性的实现是废话,我不知道为什么他们认为绑定TextBlock
而不是ContentPresenter
是个好主意。
我建议使用附加属性或具有相应属性的子类来覆盖它。 您只需要创建一个包含ContentPresenter
的DataTemplate
,其Content
绑定到目标属性,这将允许隐式DataTemplating
。 然后,应将此延迟DataTemplate
指定为列的CellTemplate
。