How do you use a DataType-targeted DataTemplate together with GridView?

有些话、适合烂在心里 提交于 2019-12-03 20:34:41

WPF allows you to insert objects such as ViewModels in the Logical Tree, while a DataTemplate can be used to tell WPF how to draw the specified object when drawing the Visual Tree.

An implicit DataTemplate is a DataTemplate that only has a DataType defined (no x:Key), and it will be used automatically whenever WPF tries to render an object of the specified type in the VisualTree.

So, you can use

<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>

to tell WPF to draw ViewModelA with ViewA, ViewModelB with ViewB, and ViewModelC with ViewC.

If you only want this applied to your GridView instead of to the entire Window, you can specify <GridView.Resources> (or <ListView.Resources>, I can't remember which one)

It should be noted that if you are binding your column using the DisplayMemberBinding, it will render as a TextBox with the Text value bound to your property, which means it will render YourViewModel.ToString() instead of trying to draw the ViewModel in the VisualTree using your DataTemplate.

To avoid that, simply set the CellTemplate to something like a ContentPresenter with the Content property bound to your ViewModel, and it will render your ViewModel using your implicit DataTemplates

<GridViewColumn Header="Some Header">
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <ContentPresenter Content="{Binding YourViewModelProperty}" />
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

The implementation of DisplayMember* properties is crap, i have no idea why they thought that binding a TextBlock instead of a ContentPresenter would be a good idea.

I would recommend an attached property or a subclass with a respective property to override this. You just need to make it create a DataTemplate containing a ContentPresenter whose Content is bound to the targeted property, that will allow for implicit DataTemplating. This deferring DataTemplate then should be assigned as the CellTemplate of the column.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!