DataTemplate для каждого типа данных в Gridviewcolumn CellTemplate
У меня есть ObservableCollection, который содержит модели представления нескольких типов, и я хотел бы сделать DataTemplate для каждого типа в каждой из моих Gridviewcolumn CellTemplates. В этом простом примере я мог бы создать базовую ViewModel, но я хотел бы иметь возможность сделать это только из xaml. Xaml ниже показывает, что я пытаюсь сделать, где одна из DataTemplates будет использоваться для каждой CellTemplate.
Если бы был GridViewColumn.Ресурсы я бы определил Затем DataTemplates использует DataTemplate с ContentPresenter в CellTemplate, но я, очевидно, не могу этого сделать. Я думаю, что мне может понадобиться TemplateSelector, но я не уверен, с чего начать.
<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>
1 ответов
есть несколько различных способов, которыми вы могли бы пойти здесь. Вы можете написать DataTemplateSelector и назначить это GridViewColumn.CellTemplateSelector
свойства:
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 для краткости:
<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, вы можете положиться на типы данных для разрешения правильных шаблонов для вас. Обычно вы просто помещаете их в коллекцию ресурсов ближайший контейнер, но, к сожалению, GridViewColumn не является элементом пользовательского интерфейса, поэтому не имеет коллекции ресурсов. Вы можете обойти это, добавив ContentControl для каждой ячейки, которая может содержать свои собственные типизированные шаблоны:
<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>
в любом случае должен дать вам тот же результат.