如何将与DataView一起使用的DataTemplate与GridView一起使用?

在回答之前:这个问题是关于WPF的ListView控件(使用GridView )。 它不是关于WPF的DataGrid控件,ASP.NET的DataGridListView控件,或WinForm的DataGridViewListView控件。 它们听起来非常相似并且经常混淆,但错误控制类型的答案对我来说无益,更重要的是浪费了你写答案的时间,我认为不应该浪费。


我有一个带有GridViewListView控件,它有几个绑定到我的视图模型属性的列。 我可以通过指定CellTemplate (内联或通过资源)轻松自定义GridViewColumn单元格的可视外观。

现在我的视图模型上有一个特定的属性; 它的类型是一个抽象基类,它的值可以是几种派生类型之一。 每个派生类型应在单元格中具有不同的DataTemplate 。 幸运的是, GridViewColumn有一个CellTemplateSelector ,它完全符合我的要求,但需要编写一些管道代码。 但是看一下DataTemplateSelector的页面,它说:

请注意,如果您有不同类型的对象,则可以在DataTemplate上设置DataType属性。 如果这样做,则无需创建DataTemplateSelector。 […]有关更多信息,请参阅数据模板概述 。

欢呼! 无需编写管道代码。 我的类型不同,所以这似乎是一个完美的契合。 但是,即使我定义了一个DataTemplate ,其DataType与其中一个DataTemplate绑定列(使用GridViewColumnDisplayMemberBinding绑定)的特定派生类型相匹配,它也没有效果。

我只想根据GridView某个列的运行时类型显示不同的DataTemplateDataType -targeted DataTemplates是否与GridView不兼容? 有没有办法使用它们,还是我必须使用指定CellTemplateSelector ? 也许有一种方法可以在GridViewColumnCellTemplate指定多个DataTemplate ,这样DataType属性就会产生影响?

WPF允许您在逻辑树中插入ViewModels等对象,而DataTemplate可用于告诉WPF在绘制Visual Tree时如何绘制指定的对象。

隐式DataTemplate是一个只定义了DataTypeDataTemplate (无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是个好主意。

我建议使用附加属性或具有相应属性的子类来覆盖它。 您只需要创建一个包含ContentPresenterDataTemplate ,其Content绑定到目标属性,这将允许隐式DataTemplating 。 然后,应将此延迟DataTemplate指定为列的CellTemplate