WPF Dynamically Generated DataGrid

When building an application, I might not have the luxury of creating model classes to represent the objects I'll be rendering on screen, because they are dynamic. If I don't know the shape of my data, I can use a meta model (a model of the final model) to represent it.

Some examples of where this exist are:

  • SharePoint - users can define custom lists with custom columns, so a particular ListItem has many "properties"
  • Microsoft CRM - users can define custom entities, again with custom attributes

For example, I might have the concept of a Property:

public class Property : INotifyPropertyChanged
    public Property(string name, object value)
        Name = name;
        Value = value;

    public string Name { get; private set; }
    public object Value { get; set; }

And the concept of a Record, which is really just a bag of properties:

public class Record
    private readonly ObservableCollection<Property> properties = new ObservableCollection<Property>();

    public Record(params Property[] properties)
        foreach (var property in properties)

    public ObservableCollection<Property> Properties
        get { return properties; }

Here's how I might fill the data:

var records = new ObservableCollection<Record>();
records.Add(new Record(new Property("FirstName", "Paul"), new Property("LastName", "Stovell")));
records.Add(new Record(new Property("FirstName", "Tony"), new Property("LastName", "Black")));

Rendering basic columns in a DataGrid

Building a DataGrid to render this model is pretty easy. The XAML would be:

   ItemsSource="{Binding Path=Records}" 

Since I don't know the names of the columns at design time, I'll have to dynamically generate them. This part is easy:

var columns = records.First()
    .Select((x, i) => new {Name = x.Name, Index = i})

foreach (var column in columns)
    var binding = new Binding(string.Format("Properties[{0}].Value", column.Index));

    dataGrid.Columns.Add(new DataGridTextColumn() {Header = column.Name, Binding = binding });

As you can see, I dynamically create a Binding, and use the index of the column in my model as the binding path.

Rendering templated columns

This part gets harder. If I wanted to use a custom CellTemplate to render my properties, I might have done this in XAML:

            <Border Padding="3" Background="Purple">
                <TextBox Text="{Binding Path=FirstName}" />

Notice I hardcoded Path=FirstName in the binding above - that's not going to work when we have a dynamic model.

It took a lot of experimentation to make this happen, but the result isn't much more complicated. I'd start by making a DataTemplate for the cell as a resource:


    <DataTemplate x:Key="CustomTemplate">
        <Border Padding="3" Background="Purple">
            <TextBox Text="{Binding Path=Value}" />


I'd then dynamically generate the columns like this:

foreach (var column in columns)
    var binding = new Binding(string.Format("Properties[{0}]", column.Index));
    dataGrid.Columns.Add(new CustomBoundColumn() 
        Header = column.Name, 
        Binding = binding, 
        TemplateName = "CustomTemplate" 

The part that makes it work is the CustomBoundColumn - I had to implement this myself. Here it is:

public class CustomBoundColumn : DataGridBoundColumn
    public string TemplateName { get; set; }

    protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
        var binding = new Binding(((Binding)Binding).Path.Path);
        binding.Source = dataItem;

        var content = new ContentControl();
        content.ContentTemplate = (DataTemplate)cell.FindResource(TemplateName);
        content.SetBinding(ContentControl.ContentProperty, binding);
        return content;

    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
        return GenerateElement(cell, dataItem);

Note that the name of the DataTemplate is passed as a property to the CustomBoundColumn, so you could dynamically choose a DataTemplate to use based on the type of property (e.g., use a different template if the value is numeric).

A picture of me

Welcome, my name is Paul Stovell. I live in Brisbane and work on Octopus Deploy, an automated deployment tool for .NET applications.

Prior to founding Octopus Deploy, I worked for an investment bank in London building WPF applications, and before that I worked for Readify, an Australian .NET consulting firm. I also worked on a number of open source projects and was an active user group presenter. I was a Microsoft MVP for WPF from 2006 to 2013.

04 Apr 2011

You can also use a dependency property to bind a listview to an unknown dataset. Check out this article on the code project. Binding a ListView to a Data Matrix

05 Apr 2011

We used the ICustomTypeDescriptor interface for such a task but that will get messy fast. Another problem is that your property must inherit from PropertyDescriptor. I will definitely look into this solution and that one provided by tawani.

06 Apr 2011

Excellent article, can I download the code? TIA Yaz

17 May 2011

I got the following error using your code:

Error 1 'MVVM.ViewModel.DGProperty' does not implement interface member 'System.ComponentModel.INotifyPropertyChanged.PropertyChanged' C:\Users\MVVM\ViewModel\DGProperty.cs

I assume I have to add an event handler per:


21 May 2011

I would love to see this work. I may just be missing something, but I can't get the binding with "Properties[{0}].Value" to work. I am not sure how much of the DataGrid xaml needs to stay in the final working code. Or, perhaps where to be adding Records/Columns. Not exactly sure what is missing. Or, maybe the delta between lower case records and upper case Records? In any case, I like the idea, but a working example would rock.

Thanks for taking the time.

22 May 2011


What errors are you getting? Can you post the code? (Indent by four spaces)