GridViewColumn CellTemplate中每个DataType的DataTemplate [英] DataTemplate for each DataType in a GridViewColumn CellTemplate

查看:76
本文介绍了GridViewColumn CellTemplate中每个DataType的DataTemplate的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ObservableCollection,其中包含多种类型的视图模型,我想为每个GridViewColumn的CellTemplates中的每种类型创建一个DataTemplate.在这个简单的示例中,我可以创建一个基本的ViewModel,但是我希望能够仅通过xaml做到这一点.下面的xaml显示了我正在尝试执行的操作,其中每个单元模板都将使用一个DataTemplates.

I have an ObservableCollection which contains view models of multiple types, and I would like to make a DataTemplate for each type within each of my GridViewColumn's CellTemplates. In this simple example I could create a base ViewModel, but I would like to be able to do this just from xaml. The xaml below shows what I am trying to do, where one of the DataTemplates would be used for each CellTemplate.

如果有GridViewColumn.Resources,我将在其中定义DataTemplates,然后在CellTemplate中使用带有ContentPresenter的DataTemplate,但是我显然不能做到这一点.我在想可能需要一个TemplateSelector,但是我不确定从哪里开始.

If there were a GridViewColumn.Resources I would define the DataTemplates there then use a a DataTemplate with ContentPresenter in the CellTemplate, but I obviously can't do that. I'm thinking I may need a TemplateSelector, but I'm not sure where to start.

<ListView ItemsSource={Binding GenericObservableCollection>
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Type">
                <GridViewColumn.CellTemplate>
                    <DataTemplate DataType="{x:Type vm:ActionInputViewModel}">
                        <TextBlock Text="Input"/>
                    </DataTemplate>
                    <DataTemplate DataType="{x:Type vm:ActionOutputViewModel}">
                        <TextBlock Text="Output"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Header="Value">
                <GridViewColumn.CellTemplate>
                    <DataTemplate DataType="{x:Type vm:ActionInputViewModel}">
                        <TextBlock Text="{Binding Property1}"/>
                    </DataTemplate>
                    <DataTemplate DataType="{x:Type vm:ActionOutputViewModel}">
                        <TextBlock Text="{Binding Property2}"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

推荐答案

您可以通过几种不同的方式来这里.您可以编写一个DataTemplateSelector并将其分配给GridViewColumn.CellTemplateSelector属性:

There are a few different ways you could go here. You could write a DataTemplateSelector and assign that to the GridViewColumn.CellTemplateSelector property:

public class ViewModelTemplateSelector : DataTemplateSelector
{
    public DataTemplate InputTemplate { get; set; }
    public DataTemplate OutputTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        return (item is ActionInputViewModel) ? InputTemplate : OutputTemplate;
    }
}

然后,您可以将所有模板移动到资源中的某个位置-为了简洁起见,这里我将其粘贴在ListView中:

Then you can move all the templates to Resources somewhere - here I've just stuck it in the ListView for brevity:

    <ListView ItemsSource="{Binding GenericObservableCollection}">
        <ListView.Resources>
            <DataTemplate x:Key="InLabel" DataType="{x:Type vm:ActionInputViewModel}">
                <TextBlock Text="Input"/>
            </DataTemplate>
            <DataTemplate x:Key="OutLabel" DataType="{x:Type vm:ActionOutputViewModel}">
                <TextBlock Text="Output"/>
            </DataTemplate>
            <DataTemplate x:Key="InValue" DataType="{x:Type vm:ActionInputViewModel}">
                <TextBlock Text="{Binding Property1}"/>
            </DataTemplate>
            <DataTemplate x:Key="OutValue" DataType="{x:Type vm:ActionOutputViewModel}">
                <TextBlock Text="{Binding Property2}"/>
            </DataTemplate>
        </ListView.Resources>
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Type">
                    <GridViewColumn.CellTemplateSelector>
                        <vm:ViewModelTemplateSelector InputTemplate="{StaticResource InLabel}" OutputTemplate="{StaticResource OutLabel}"/>
                    </GridViewColumn.CellTemplateSelector>
                </GridViewColumn>
                <GridViewColumn Header="Value">
                    <GridViewColumn.CellTemplateSelector>
                        <vm:ViewModelTemplateSelector InputTemplate="{StaticResource InValue}" OutputTemplate="{StaticResource OutValue}"/>
                    </GridViewColumn.CellTemplateSelector>
                </GridViewColumn>
            </GridView>
        </ListView.View>
    </ListView>

或者,如果您希望将其全部保留在XAML中,则可以依靠DataType为您解析正确的模板.通常,您只是将它们放入最近的容器的Resources集合中,但是不幸的是GridViewColumn不是UI元素,因此没有Resources集合.您可以通过为每个可以添加自己的类型化模板的单元格添加一个ContentControl来解决此问题:

Alternatively, if you want to keep it all in XAML you can rely on the DataTypes to resolve the right templates for you. Normally you would just put them into the Resources collection of the closest container but unfortunately GridViewColumn isn't a UI element so doesn't have a Resources collection. You can get around this by adding in a ContentControl for each cell which can hold its own typed templates:

    <ListView ItemsSource="{Binding GenericObservableCollection}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Type">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <ContentControl Content="{Binding}">
                                <ContentControl.Resources>
                                    <DataTemplate DataType="{x:Type vm:ActionInputViewModel}">
                                        <TextBlock Text="Input"/>
                                    </DataTemplate>
                                    <DataTemplate DataType="{x:Type vm:ActionOutputViewModel}">
                                        <TextBlock Text="Output"/>
                                    </DataTemplate>
                                </ContentControl.Resources>
                            </ContentControl>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn Header="Value">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <ContentControl Content="{Binding}">
                                <ContentControl.Resources>
                                    <DataTemplate DataType="{x:Type vm:ActionInputViewModel}">
                                        <TextBlock Text="{Binding Property1}"/>
                                    </DataTemplate>
                                    <DataTemplate DataType="{x:Type vm:ActionOutputViewModel}">
                                        <TextBlock Text="{Binding Property2}"/>
                                    </DataTemplate>
                                </ContentControl.Resources>
                            </ContentControl>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
            </GridView>
        </ListView.View>
    </ListView>

任何一种方法都应该给您相同的结果.

Either way should give you the same result.

这篇关于GridViewColumn CellTemplate中每个DataType的DataTemplate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆