Skip to main content

Choosing Templates Based on Custom Logic

  • 3 minutes to read

Columns and Views provide multiple properties that allow you to define templates and change the visual presentation of their elements (cells, rows, summary items, etc.). A template is applied to multiple elements in the same scope. If however, you have more than one template that can be applied to a target element (e.g. a cell, row), you can implement custom logic to choose the required template. This allows you to provide a different visual appearance for individual grid elements.

For example, a template that defines the presentation of data rows is specified by the TableView.DataRowTemplate property. If you want to conditionally apply templates to them:

  • Create a template selector - a class that chooses a template if the required condition is met. This class must derive from the DataTemplateSelector class and override the SelectTemplate method, to return a template which meets the required condition.
  • Assign its instance to the TableView.DataRowTemplateSelector property.

Example 1: Apply Row Templates Based on Custom Logic

This example demonstrates how to use DataRowTemplateSelector to apply different templates to even and odd data rows.

Grid - RowTemplateSelector

View Example: Select a Row Template Based on Custom Logic

<Window.Resources>
    <DataTemplate x:Key="evenRowTemplate">
        <Border Margin="1"
                Background="Blue"
                CornerRadius="5">
            <TextBlock Margin="5"
                       Foreground="White"
                       Text="{Binding Row.IssueName}"/>
        </Border>
    </DataTemplate>
    <DataTemplate x:Key="oddRowTemplate">
        <Border Margin="1"
                Background="Orange"
                CornerRadius="5">
            <TextBlock Margin="5"
                       Foreground="White"
                       Text="{Binding Row.IssueName}"/>
        </Border>
    </DataTemplate>
    <local:RowTemplateSelector x:Key="rowTemplateSelector"
                               EvenRowTemplate="{StaticResource evenRowTemplate}"
                               OddRowTemplate="{StaticResource oddRowTemplate}"/>
</Window.Resources>
<dxg:GridControl x:Name="grid" AutoGenerateColumns="AddNew">
    <dxg:GridControl.View>
        <dxg:TableView AutoWidth="True" DataRowTemplateSelector="{StaticResource rowTemplateSelector}"/>
    </dxg:GridControl.View>
</dxg:GridControl>
public class RowTemplateSelector : DataTemplateSelector {
    public DataTemplate EvenRowTemplate { get; set; }
    public DataTemplate OddRowTemplate { get; set; }
    public override DataTemplate SelectTemplate(object item, DependencyObject container) {
        RowData row = item as RowData;
        if (row != null)
            return row.EvenRow ? EvenRowTemplate : OddRowTemplate;
        return base.SelectTemplate(item, container);
    }
}

Example 2: Change a Cell Template Based on Custom Logic

This sample illustrates how to use the CellTemplateSelector to change a cell template based on a condition:

Grid - CellTemplateSelector

View Example: Change a Cell Template Based on Custom Logic

To implement this approach, do the following:

  1. Implement custom DataTemplates. Editors declared in these templates should follow our recommendations from this help topic: ColumnBase.CellTemplate:

    <Window.Resources>
        <DataTemplate x:Key="booleanEditor">
            <dxe:CheckEdit Name="PART_Editor" />
        </DataTemplate>
        <DataTemplate x:Key="buttonEditor">
            <dxe:ButtonEdit Name="PART_Editor" />
        </DataTemplate>
        <DataTemplate x:Key="comboboxEditor">
            <dxe:ComboBoxEdit Name="PART_Editor">
                <dxe:ComboBoxEdit.ItemsSource>
                    <collections:ArrayList>
                        <dx:Alignment>Near</dx:Alignment>
                        <dx:Alignment>Center</dx:Alignment>
                        <dx:Alignment>Far</dx:Alignment>
                    </collections:ArrayList>
                </dxe:ComboBoxEdit.ItemsSource>
            </dxe:ComboBoxEdit>
        </DataTemplate>
        <DataTemplate x:Key="dateEditor">
            <dxe:DateEdit Name="PART_Editor" />
        </DataTemplate>
        <DataTemplate x:Key="textEditor">
            <dxe:TextEdit Name="PART_Editor" />
        </DataTemplate>
    </Window.Resources>
    
    <dxg:GridControl Name="grid">
        <dxg:GridControl.Columns>
            <dxg:GridColumn FieldName="Editor" />
            <dxg:GridColumn FieldName="Value">
                <dxg:GridColumn.CellTemplateSelector>
                    <local:EditorTemplateSelector />
                </dxg:GridColumn.CellTemplateSelector>
            </dxg:GridColumn>
        </dxg:GridControl.Columns>
        <dxg:GridControl.View>
            <dxg:TableView Name="view" AutoWidth="True" EditorButtonShowMode="ShowAlways" />
        </dxg:GridControl.View>
    </dxg:GridControl> 
    
  2. Create a custom DataTemplateSelector descendant. This descendant should return templates according to your scenario requirements.

    Note

    Each GridControl cell contains an object of the EditGridCellData data type in its DataContext. This object’s RowData.Row property contains your data item. You can use this property if your logic should take property values from data items into account:

    public class EditorTemplateSelector : DataTemplateSelector {
        public override DataTemplate SelectTemplate(object item, DependencyObject container) {
            EditGridCellData data = (EditGridCellData)item;
            var dataItem = data.RowData.Row as TestData;
            return string.IsNullOrEmpty(dataItem.Editor) ? null : (DataTemplate)((FrameworkElement)container).FindResource(dataItem.Editor);
        }
    } 
    
See Also