How to: Customize Auto-Generated Columns in the DataGrid Control

Microsoft Silverlight will reach end of support after October 2021. Learn more.

You can handle the AutoGeneratingColumn event to modify, replace, or cancel a column that is being generated. The AutoGeneratingColumn event occurs one time for each public, non-static property in the bound data type when the ItemsSource property is changed and the AutoGenerateColumns property is true.

To handle the AutoGeneratingColumn event

  1. Create an event handler for the DataGrid's AutoGeneratingColumn event.

    Private Sub dataGrid1_AutoGeneratingColumn(ByVal sender As System.Object, ByVal e As System.Windows.Controls.DataGridAutoGeneratingColumnEventArgs)
    
    
    ...
    
    
    End Sub
    
    private void dataGrid1_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
    
    
    ...
    
    
    }
    
  2. Add the event handler to the DataGrid instances events.

    <sdk:DataGrid x:Name="dataGrid1"
                AutoGenerateColumns="True"
                AutoGeneratingColumn="dataGrid1_AutoGeneratingColumn"/>
    

To modify a generated column

To replace a generated column

  1. In the AutoGeneratingColumn event handler, create a new DataGridColumn.

    '  Replace the DueDate column with a custom template column.
    If e.PropertyName = "DueDate" Then
        ' Create a new template column.
        Dim templateColumn As New DataGridTemplateColumn
        templateColumn.Header = "Due Date"
        templateColumn.CellTemplate = Me.Resources("dueDateCellTemplate")
        templateColumn.CellEditingTemplate = Me.Resources("dueDateCellEditingTemplate")
        templateColumn.SortMemberPath = "DueDate"
        ' ...
    
    // Replace the DueDate column with a custom template column.
    if (e.PropertyName == "DueDate")
    {
        // Create a new template column.
        DataGridTemplateColumn templateColumn = new DataGridTemplateColumn();
        templateColumn.Header = "Due Date";
        templateColumn.CellTemplate = (DataTemplate)Resources["dueDateCellTemplate"];
        templateColumn.CellEditingTemplate = (DataTemplate)Resources["dueDateCellEditingTemplate"];
        templateColumn.SortMemberPath = "DueDate";
        // ...
    
  2. Replace the column from the DataGridAutoGeneratingColumnEventArgs.Column property with the new DataGridColumn instance.

    ' Replace the auto-generated column with the templateColumn.
    e.Column = templateColumn
    
    // Replace the auto-generated column with the templateColumn.
    e.Column = templateColumn;
    

To cancel generation of a column

  • Set the Cancel property to true.

    ' Cancel AutoGeneration of all boolean columns.
    If e.PropertyType Is GetType(Boolean) Then
        e.Cancel = True
    End If
    
    // Cancel AutoGeneration of all boolean columns.
    if (e.PropertyType == typeof(bool))
        e.Cancel = true;
    

Example

The following code example creates a List<T> of Task objects, and displays the task list in a DataGrid.named dataGrid1. In the AutoGeneratingColumn event handler of dataGrid1, the following customizations are made.

  • The Header of the 'Name' column is modified to display 'Task'.

  • The auto-generated DueDate column is replaced with a custom DataGridTemplateColumn.

  • The auto generation of all columns that display Boolean data is canceled.

<!-- NOTE: 
  By convention, the sdk prefix indicates a URI-based XAML namespace declaration 
  for Silverlight SDK client libraries. This namespace declaration is valid for 
  Silverlight 4 only. In Silverlight 3, you must use individual XAML namespace 
  declarations for each CLR assembly and namespace combination outside the scope 
  of the default Silverlight XAML namespace. For more information, see the help 
  topic "Prefixes and Mappings for Silverlight Libraries". 
-->
<UserControl 
    xmlns:sdk="https://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
    x:Class="DGAutoGenColumn.Page"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300">
    <UserControl.Resources>
        <DataTemplate x:Key="dueDateCellTemplate">
            <TextBlock
            Text="{Binding DueDate}"
            Margin="5,4,5,4" />
        </DataTemplate>
        <DataTemplate x:Key="dueDateCellEditingTemplate">
            <sdk:DatePicker 
            SelectedDate="{Binding DueDate, Mode=TwoWay}" />
        </DataTemplate>
    </UserControl.Resources>
    <StackPanel x:Name="LayoutRoot" Background="White" Margin="5">
        <TextBlock Text="Column AutoGeneration" Foreground="#FF5C9AC9"
                   FontSize="18" FontFamily="Verdana" FontWeight="Bold" />
        <sdk:DataGrid x:Name="dataGrid1"
                   AutoGenerateColumns="True"
                   AutoGeneratingColumn="dataGrid1_AutoGeneratingColumn" />
    </StackPanel>
</UserControl>
Partial Public Class Page
    Inherits UserControl

    Public Sub New()
        InitializeComponent()
        '  Generate some task data and add it to the task list.
        Dim taskList As List(Of Task) = New List(Of Task)
        For index = 1 To 10
            taskList.Add(New Task() With _
                         {.Name = "Task " & index.ToString(), _
                           .DueDate = Date.Now.AddDays(index), _
                           .Complete = (index Mod 3 = 0), _
                           .Notes = "add notes..." _
                         })
        Next
        Me.dataGrid1.ItemsSource = taskList
    End Sub
    Private Sub dataGrid1_AutoGeneratingColumn(ByVal sender As System.Object, ByVal e As System.Windows.Controls.DataGridAutoGeneratingColumnEventArgs)
        ' Modify the header of the Name column.
        If e.Column.Header.ToString() = "Name" Then
            e.Column.Header = "Task"
        End If
        '  Replace the DueDate column with a custom template column.
        If e.PropertyName = "DueDate" Then
            ' Create a new template column.
            Dim templateColumn As New DataGridTemplateColumn
            templateColumn.Header = "Due Date"
            templateColumn.CellTemplate = Me.Resources("dueDateCellTemplate")
            templateColumn.CellEditingTemplate = Me.Resources("dueDateCellEditingTemplate")
            templateColumn.SortMemberPath = "DueDate"
            ' ...
            ' Replace the auto-generated column with the templateColumn.
            e.Column = templateColumn

        End If
        ' Cancel AutoGeneration of all boolean columns.
        If e.PropertyType Is GetType(Boolean) Then
            e.Cancel = True
        End If
    End Sub
End Class

Public Class Task
    Private m_Name As String
    Private m_DueDate As Date
    Private m_Complete As Boolean
    Private m_Notes As String

    Property Name() As String
        Get
            Return Me.m_Name
        End Get
        Set(ByVal value As String)
            Me.m_Name = value
        End Set
    End Property

    Property DueDate() As Date
        Get
            Return Me.m_DueDate
        End Get
        Set(ByVal value As Date)
            Me.m_DueDate = value
        End Set
    End Property

    Property Complete() As Boolean
        Get
            Return Me.m_Complete
        End Get
        Set(ByVal value As Boolean)
            Me.m_Complete = value
        End Set
    End Property

    Property Notes() As String
        Get
            Return Me.m_Notes
        End Get
        Set(ByVal value As String)
            Me.m_Notes = value
        End Set
    End Property
End Class
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace DGAutoGenColumn
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
            // Generate some task data and add it to the task list.
            List<Task> taskList = new List<Task>();
            for (int i = 1; i <= 10; i++)
            {
                taskList.Add(new Task()
                {
                    Name = "Task " + i.ToString(),
                    DueDate = DateTime.Now.AddDays(i),
                    Complete = (i % 3 == 0),
                    Notes = "add notes..."
                });
            }
            this.dataGrid1.ItemsSource = taskList;
        }

        private void dataGrid1_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
        {
            // Modify the header of the Name column.
            if (e.Column.Header.ToString() == "Name")
                e.Column.Header = "Task";
            // Replace the DueDate column with a custom template column.
            if (e.PropertyName == "DueDate")
            {
                // Create a new template column.
                DataGridTemplateColumn templateColumn = new DataGridTemplateColumn();
                templateColumn.Header = "Due Date";
                templateColumn.CellTemplate = (DataTemplate)Resources["dueDateCellTemplate"];
                templateColumn.CellEditingTemplate = (DataTemplate)Resources["dueDateCellEditingTemplate"];
                templateColumn.SortMemberPath = "DueDate";
                // ...
                // Replace the auto-generated column with the templateColumn.
                e.Column = templateColumn;
            }

            // Cancel AutoGeneration of all boolean columns.
            if (e.PropertyType == typeof(bool))
                e.Cancel = true;
        }
    }

    public class Task
    {
        public string Name { get; set; }
        public DateTime DueDate { get; set; }
        public bool Complete { get; set; }
        public string Notes { get; set; }
    }
}

To view a running sample of the DataGrid control, click the following link.

Run this sample