Switching Controls Between Display and Edit Modes in WPF DataGrid Cells

Use DataGridTemplateColumn with CellTemplate and CellEditingTemplate to separate display UI from editing UI in WPF DataGrid.

Overview

In WPF DataGrid, the standard way to switch controls between display mode and cell edit mode is to separate CellTemplate and CellEditingTemplate in DataGridTemplateColumn. This article explains the core implementation, common applied patterns, and practical criteria for deciding when CellEditingTemplate should be used.

Prerequisites / Environment

Problem

When only standard columns such as DataGridTextColumn are used, display mode and edit mode often look almost identical. This leads to two frequent issues: too many input-like controls in a read-focused list view, and insufficient editing assistance when users actually start editing.

Cause / Background

Display mode and edit mode have different goals. Display mode prioritizes lightweight rendering and readability, while edit mode prioritizes input constraints and operability. Trying to satisfy both goals with one control usually compromises one side. DataGrid already provides a mode switch mechanism, so separating display and editing templates is the more maintainable design.

Solution

Use DataGridTemplateColumn and define CellTemplate for normal display and CellEditingTemplate for editing. DataGrid switches between these templates automatically when editing starts and ends. This separation keeps the list UI simple while still enabling richer editing controls such as TextBox, ComboBox, or DatePicker.

Implementation

The first example shows the minimum recommended structure: TextBlock for display and TextBox for editing. This is the clearest way to separate read and edit responsibilities.

<DataGrid ItemsSource="{Binding Items}">
  <DataGrid.Columns>
    <DataGridTemplateColumn Header="Name">
      <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
          <TextBlock Text="{Binding Name}" />
        </DataTemplate>
      </DataGridTemplateColumn.CellTemplate>
      <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
          <TextBox Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        </DataTemplate>
      </DataGridTemplateColumn.CellEditingTemplate>
    </DataGridTemplateColumn>
  </DataGrid.Columns>
</DataGrid>

When editing starts, the grid uses CellEditingTemplate. When editing ends, it returns to CellTemplate. No manual event-based UI switching is required.

The next pattern applies input constraints with ComboBox only during editing. This pattern reduces invalid input while keeping normal display lightweight.

<DataGridTemplateColumn Header="Category">
  <DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding Category}" />
    </DataTemplate>
  </DataGridTemplateColumn.CellTemplate>
  <DataGridTemplateColumn.CellEditingTemplate>
    <DataTemplate>
      <ComboBox
        ItemsSource="{Binding DataContext.Categories, RelativeSource={RelativeSource AncestorType=DataGrid}}"
        SelectedItem="{Binding Category, Mode=TwoWay}" />
    </DataTemplate>
  </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

The candidate list is read from the grid-level DataContext, which keeps row item data and selectable options cleanly separated. This structure scales better when option lists need localization or central management.

A single-template approach is also possible by binding to DataGridCell.IsEditing and toggling visibility with a trigger. This can satisfy special UI requirements, but it tends to increase XAML complexity.

<DataTemplate>
  <Grid>
    <TextBlock x:Name="display" Text="{Binding Name}" />
    <TextBox x:Name="editor" Text="{Binding Name, Mode=TwoWay}" Visibility="Collapsed" />
    <DataTemplate.Triggers>
      <DataTrigger
        Binding="{Binding RelativeSource={RelativeSource AncestorType=DataGridCell}, Path=IsEditing}"
        Value="True">
        <Setter TargetName="display" Property="Visibility" Value="Collapsed" />
        <Setter TargetName="editor" Property="Visibility" Value="Visible" />
      </DataTrigger>
    </DataTemplate.Triggers>
  </Grid>
</DataTemplate>

This approach is valid for specific cases, but CellTemplate plus CellEditingTemplate should remain the default policy for maintainability and predictability.

Notes

Alternatives / Comparison

Summary

CellEditingTemplate is primarily used to separate display-oriented UI from input-oriented UI. Use it when display and editing controls should differ, when inputs need constraints, or when edit controls are expensive and should be instantiated only during editing. For plain text editing with no special interaction, standard DataGrid columns are usually the more efficient choice.