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

All*_*nek 2 .net c# wpf xaml datatemplate

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


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

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

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

欢呼!无需编写管道代码.我的类型不同的,因此这似乎是一个完美的结合.但是,即使在我定义了DataTemplate一个DataType匹配数据绑定列之一(使用GridViewColumn's 绑定)的特定派生类型之后DisplayMemberBinding,它也没有效果.

我只想DataTemplate根据我的某个列的运行时类型显示不同的GridView.是DataType靶向性DataTemplates根本不兼容GridView?有没有办法使用它们,还是我必须指定一个CellTemplateSelector?或许有指定多个方式DataTemplate在s GridViewColumnCellTemplate,这样DataType属性将产生效果?

Rac*_*hel 7

WPF允许您插入对象,例如ViewModels在逻辑树中,而a DataTemplate可以用于告诉WPF在绘制可视树时如何绘制指定的对象.

隐式DataTemplateDataTemplate只有一个已DataType定义的(no x:Key),并且只要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>
Run Code Online (Sandbox Code Playgroud)

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

如果你只想将它应用到你的GridView而不是整个Window,你可以指定<GridView.Resources>(或者<ListView.Resources>,我不记得哪一个)

应该注意的是,如果使用the绑定列DisplayMemberBinding,它将呈现为绑定到您的属性TextBoxText值,这意味着它将呈现YourViewModel.ToString()而不是尝试使用您的VisualTree中的ViewModel DataTemplate.

为了避免这种情况,只需将CellTemplate要像一个ContentPresenterContent绑定到你的财产ViewModel,它会使用您的暗示使您的视图模型DataTemplates

<GridViewColumn Header="Some Header">
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <ContentPresenter Content="{Binding YourViewModelProperty}" />
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>
Run Code Online (Sandbox Code Playgroud)