2

在您回答之前:这个问题是关于 WPF 的ListView控件(带有GridView)。它与 WPF 的控件、ASP.NET或控件或 WinForm或控件无关。它们听起来都非常相似并且经常被混淆,但是对于错误类型的控制的答案对我来说既没有帮助,更重要的是浪费了你写答案的时间,我认为不应该浪费。DataGridDataGridListViewDataGridViewListView


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

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

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

欢呼!无需编写管道代码。我的类型不同,所以这看起来很合适。但是,唉,即使我DataTemplate用 a 定义了与DataType数据绑定列之一的特定派生类型匹配的 a (使用GridViewColumn's绑定DisplayMemberBinding),它也没有效果。

我只是想DataTemplate根据我的GridView. DataType-targeted是否DataTemplatesGridView? 有没有办法使用它们,或者我必须求助于指定一个CellTemplateSelector?也许有一种方法可以在'sDataTemplate内指定多个 s ,以便该属性产生效果?GridViewColumnCellTemplateDataType

4

2 回答 2

7

ViewModelsWPF 允许您在逻辑树中插入对象,而DataTemplate在绘制可视树时可以使用 a 来告诉 WPF 如何绘制指定的对象。

隐式DataTemplateDataTemplate只有一个已DataType定义(no x:Key)的 a,每当 WPF 尝试在 VisualTree 中呈现指定类型的对象时,它都会自动使用。

所以,你可以使用

<Window.Resources>

    <DataTemplate DataType="{x:Type local:ViewModelA}">
        <local:ViewA />
    </DataTemplate>

    <DataTemplate DataType="{x:Type local:ViewModelB}">
        <local:ViewB />
    </DataTemplate>

    <DataTemplate DataType="{x:Type local:ViewModelC}">
        <local:ViewC />
    </DataTemplate>

</Window.Resources>

告诉 WPF 用 ViewA 绘制 ViewModelA,用 ViewB 绘制 ViewModelB,用 ViewC 绘制 ViewModelC。

如果您只想将此应用于您的 GridView 而不是整个窗口,您可以指定<GridView.Resources>(或者<ListView.Resources>,我不记得是哪一个)

应该注意的是,如果您使用 绑定列DisplayMemberBinding,它将呈现为TextBox具有绑定到您的属性的Text值的 a,这意味着它将呈现YourViewModel.ToString()而不是尝试使用您的DataTemplate.

为避免这种情况,只需将 设置CellTemplate为类似于 aContentPresenterContent属性绑定到您的ViewModel,它将使用您的隐式呈现您的 ViewModelDataTemplates

<GridViewColumn Header="Some Header">
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <ContentPresenter Content="{Binding YourViewModelProperty}" />
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>
于 2012-09-19T19:45:45.167 回答
1

属性的实现DisplayMember*是垃圾,我不知道为什么他们认为绑定 aTextBlock而不是 aContentPresenter会是一个好主意。

我会推荐一个附加属性或具有相应属性的子类来覆盖它。你只需要让它创建一个DataTemplate包含一个绑定到目标属性ContentPresenterContent,这将允许隐式DataTemplatingDataTemplate然后应将此延迟分配为CellTemplate列的。

于 2012-09-20T19:19:12.943 回答