Silverlight DataGrid: Custom Columns in Code

Scott Morrison has some excellent posts on specifying columns in a Silverlight DataGrid, but he defines all the columns in XAML.  But what if you wanted to define the columns at runtime in code?

First, let’s follow Scott’s setup to get a basic DataGrid displaying.

N.B. if you’re using the July 2009 version of the Silverlight 3 Toolkit, you’ll need to add a lot more references than Scott has:

  • System.ComponentModel.DataAnnotations
  • System.Windows.Controls.Data
  • System.Windows.Controls.Data.Input
  • System.Windows.Data

If you add all those project references, you should be able to follow his directions for a basic DataGrid.

To manually specify the columns, we set the AutoGenerateColumns property on the DataGrid to false:

 <datagrid:DataGrid x:Name="dg" AutoGenerateColumns="False"></datagrid:DataGrid>

Then we can use C# to create the columns, add bindings, and add the columns to the Grid:

 DataGridTextColumn firstNameColumn = new DataGridTextColumn()
{
    Binding = new System.Windows.Data.Binding("FirstName")
};
firstNameColumn.Header = "First Name";
dg.Columns.Add(firstNameColumn);

DataGridTextColumn lastNameColumn = new DataGridTextColumn()
{
    Binding = new System.Windows.Data.Binding("LastName")
};
lastNameColumn.Header = "Last Name";
dg.Columns.Add(lastNameColumn);

DataGridCheckBoxColumn availableColumn = new DataGridCheckBoxColumn()
{
    Binding = new System.Windows.Data.Binding("Available")
};
availableColumn.Header = "Available";
dg.Columns.Add(availableColumn);

This gives much more runtime control over the columns displayed.

Here’s the entire C# file:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace DataGridColumnsDemo
{
    public class Data
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public bool Available { get; set; }
    }

    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();
            List<Data> source = new List<Data>();
            int itemsCount = 100;

            for (int i = 0; i < itemsCount; i++)
            {
                source.Add(new Data()
                {
                    FirstName = "First" + i,
                    LastName = "Last" + i,
                    Age = i,
                    Available = (i % 2 == 0)
                });
            }

            dg.ItemsSource = source;

            DataGridTextColumn firstNameColumn = new DataGridTextColumn()
            {
                Binding = new System.Windows.Data.Binding("FirstName")
            };
            firstNameColumn.Header = "First Name";
            dg.Columns.Add(firstNameColumn);

            DataGridTextColumn lastNameColumn = new DataGridTextColumn()
            {
                Binding = new System.Windows.Data.Binding("LastName")
            };
            lastNameColumn.Header = "Last Name";
            dg.Columns.Add(lastNameColumn);

            DataGridCheckBoxColumn availableColumn = new DataGridCheckBoxColumn()
            {
                Binding = new System.Windows.Data.Binding("Available")
            };
            availableColumn.Header = "Available";
            dg.Columns.Add(availableColumn);
        }
    }
}

And the XAML file:

 <UserControl x:Class="DataGridColumnsDemo.Page"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:datagrid="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
    xmlns:basics="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
    xmlns:input="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <datagrid:DataGrid x:Name="dg" AutoGenerateColumns="False"></datagrid:DataGrid>
    </Grid>
</UserControl>