wpftypesdatagridcelltemplate

WPF DataGrid: Selecting CellTemplate by DataType of ItemsSoure


I am Building a DataGrid where i want to switch the images inside a cell based on the underlying datatype of the current item.

Question: Is it possible to apply this type of template switching? Preferably in xaml-only?

ItemsSource is

ObservableCollection<BaseModel>

which contains Items of type

IncidentModel : BaseModel
ServiceModel : BaseModel

This is where i currently am:

<DataGrid 
    ItemsSource="{Binding TicketCollection,UpdateSourceTrigger=PropertyChanged,Mode=OneWay}"
    IsReadOnly="True"
    AutoGenerateColumns="False"
    DockPanel.Dock="Top">

    <DataGrid.Resources>
        <DataTemplate DataType="{x:Type models:IncidentModel}">
            <Image Source="pack://application:,,,/SMLib;component/Files/Images/16x16/Active_16.png" />

        </DataTemplate>
        <DataTemplate DataType="{x:Type models:ServiceModel}">
            <Image Source="pack://application:,,,/SMLib;component/Files/Images/16x16/IncidentMgmt_AllIncidents_16.png" />

        </DataTemplate>
    </DataGrid.Resources>

    <DataGrid.Columns>

        <DataGridTemplateColumn Header="Typ">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>

                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

        <DataGridTextColumn Header="Id" Binding="{Binding Id,UpdateSourceTrigger=PropertyChanged,Mode=OneWay}" />
        <DataGridTextColumn Header="Titel" Binding="{Binding Title,UpdateSourceTrigger=PropertyChanged,Mode=OneWay}" />
        <DataGridTextColumn Header="Status" Binding="{Binding Status,UpdateSourceTrigger=PropertyChanged,Mode=OneWay}" />
        <DataGridTextColumn Header="Erstellung" Binding="{Binding CreatedDate,UpdateSourceTrigger=PropertyChanged,Mode=OneWay}" />
    </DataGrid.Columns>
</DataGrid>

Thanks for every possible help!


Solution

  • You could use a DataTemplateSelector

    public class MyTemplateSelector : DataTemplateSelector
    {
        public DataTemplate IncidentTemplate { get; set; }
        public DataTemplate ServiceTemplate { get; set; }
    
        public override DataTemplate SelectTemplate
            (object item, DependencyObject container)
        {
            if (item is IncidentModel) return IncidentTemplate;
            else if (item is ServiceModel) return ServiceTemplate;
            else return base.SelectTemplate(item, container);
        }
    }
    

    XAML

    <DataGrid 
    
        ...
    
        >
        <DataGrid.Resources>
            <DataTemplate x:Key="IncidentTemplate" DataType="{x:Type models:IncidentModel}">
                <Image Source="pack://application:,,,/SMLib;component/Files/Images/16x16/Active_16.png" />
            </DataTemplate>
            <DataTemplate x:Key="ServiceTemplate" DataType="{x:Type models:ServiceModel}">
                <Image Source="pack://application:,,,/SMLib;component/Files/Images/16x16/IncidentMgmt_AllIncidents_16.png" />
            </DataTemplate>
    
            <local:MyTemplateSelector x:Key="MyTemplateSelector"
                IncidentTemplate="{StaticResource IncidentTemplate}"
                ServiceTemplate="{StaticResource ServiceTemplate}" />
    
        </DataGrid.Resources>
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Typ" 
                CellTemplateSelector="{StaticResource MyTemplateSelector}" />
    
            ...
    
        </DataGrid.Columns>
    </DataGrid>