Smorkster
Smorkster

Reputation: 357

DataGrid cellstyle depending on datatype

I am trying to create a DataGrid CellStyle that changes control depending on what datatype is in the cell.

I have tried many ways for Template/ContentTemplate, with ContentControl/ItemsControl and others, but nothing reacts to anything other than strings. What I want is to be able to display a BitMap-image, if that is the data for a cell.

The content for the datagrid is not predetermined, thus can be all sorts of data, but if there is an BitMap, that image is to be displayed. There can also be any number of properties per object that is to be shown. So

The ItemsSource for the datagrid, is an ArrayList of PsCustomObject's. If the CellStyle-setter is removed, all data is displayed as strings, as it should.

The datagrid in question:

    <DataGrid>
        <DataGrid.Style>
            <Style TargetType="DataGrid">
                <Setter Property="AlternationCount"
                        Value="2" />
                <Setter Property="AutoGenerateColumns"
                        Value="True" />
                <Setter Property="CellStyle">
                    <Setter.Value>
                        <Style TargetType="DataGridCell" >
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="DataGridCell">
                                        <Grid Background="{TemplateBinding Background}">
                                            <ContentPresenter VerticalAlignment="Center" />
                                        </Grid>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </Setter.Value>
                </Setter>
                <Setter Property="HeadersVisibility"
                        Value="Column" />
                <Setter Property="IsReadOnly"
                        Value="True" />
                <Setter Property="ItemsSource"
                        Value="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=DataContext.Data}" />
                <Style.Triggers>
                    <Trigger Property="ItemsControl.AlternationIndex"
                             Value="0">
                        <Setter Property="Background"
                                Value="Transparent" />
                    </Trigger>
                    <Trigger Property="ItemsControl.AlternationIndex"
                             Value="1">
                        <Setter Property="Background"
                                Value="#e0e0e0" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </DataGrid.Style>
    </DataGrid>

EDIT Added clarification about data per object (ie row)

Upvotes: 0

Views: 63

Answers (1)

mm8
mm8

Reputation: 169420

You should be able to solve this by using a DataGridTemplateColumn with a CellTemplateSelector, e.g.:

<DataGrid ...>
    <DataGrid.Resources>
        <DataTemplate x:Key="StringTemplate">
            ...
        </DataTemplate>
        <DataTemplate x:Key="ImageTemplate">
            ...
        </DataTemplate>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="...">
            <DataGridTemplateColumn.CellTemplateSelector>
                <local:CustomTemplateSelector
                            StringTemplate="{StaticResource StringTemplate}"
                            ImageTemplate="{StaticResource ImageTemplate}" />
            </DataGridTemplateColumn.CellTemplateSelector>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

The idea is that you define a DataTemplate for each type of object in the XAML markup and then implement a custom DataTemplateSelector to select the appropriate template based on a property valye of the data object, e.g.:

public class CustomTemplateSelector : DataTemplateSelector
{
    public DataTemplate StringTemplate { get; }
    public DataTemplate ImageTemplate { get; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item is PsCustomObject customObject)
        {
            if (customObject.SomeProperty == "...")
                return StringTemplate;
            else 
                return ImageTemplate;
        }


        return base.SelectTemplate(item, container);
    }
}

Upvotes: 0

Related Questions