New User?   Join Now     Login            Forgot Password?    
Dynamic Silverlight DataGrid  (37080 hits)
 Share this Article
 
Posted by Prabu Arumugam on Jun-23-2010
Languages: C#, Silverlight

This article explains how to create dynamic columns and rows for a Silverlight DataGrid control. It helps create a new DataGrid from scratch in code-behind, populated with values from a System.Collections.Generic.Dictionary.

Dynamic DataGrid Demo in Silverlight

The techniques explained are illustrated in the following demo. The source code of the demo can be downloaded below.

Binding dynamic content to DataGrid

The following function binds a StringTable object to a Silverlight DataGrid control. The StringTable object is a simple Dictionary explained below.

private void BindStringTableToDataGrid(StringTable table, DataGrid dataGrid)
{
    dataGrid.ItemsSource = table.Values;
    dataGrid.AutoGenerateColumns = false;
	
    dataGrid.Columns.Clear();
    foreach (string columnName in table.ColumnNames)
    {
        DataGridTextColumn textColumn = new DataGridTextColumn();
        textColumn.Header = columnName;
        textColumn.Binding = new Binding();
        textColumn.Binding.Converter = new ColumnValueSelector();
        textColumn.Binding.ConverterParameter = columnName;
        dataGrid.Columns.Add(textColumn);
    }
}

Note that AutoGenerateColumns property of DataGrid is set to "false". This is to prevent DataGrid from creating columns for other properties of StringRow like Count, Keys, etc.

About StringTable

The StringTable is a simple Dictionary class with row-indices as Keys and StringRow as Values.

public class StringTable : Dictionary<int, StringRow>
{
    public List<string> ColumnNames { get; set; }
	
    public StringTable()
    {
        ColumnNames = new List<string>();
    }
}

where StringRow is an alias of the following declaration. Key is the column-name and Value is the column-value of the corresponding row.

public class StringRow : Dictionary<string, string>
{
}

For more sophisticated table data-structure with advanced helper and utility methods, see this article.

The ColumnValueSelector

The ColumnValueSelector is a converter class extended from IValueConverter. This converter is used to get the column value of the current row.

public class ColumnValueSelector : IValueConverter
{
    object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        StringRow row = (StringRow)value;
        string columnName = (string)parameter;
        return (row[columnName]);
    }
	
    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

How this works?

Since ItemsSource property of DataGrid expects a collection object, we assign it the Values property of the StringTable object. In StringTable, the column-values of each row is represented by a StringRow i.e. Dictionary<string, string>. That is, each StringRow is created as one row in the DataGrid, and each entry in the StringRow is created as one column in that row. The ColumnValueSelector is used to get the column value of the corresponding row. The column-name is passed to the converter through ConverterParameter property of the datagrid column's Binding property.


 Downloads for this article
File Language Tools
DynamicDataGrid-Demo-Source  28.35 kb  (775 downloads) C#, Silverlight 3 Visual Studio 2008

 Share this Article

 Comments on this Article
Comment by jitendra.ingale on Sep-05-2013
Can you plz impement add,edit,delete record(row) in this datagrid
Comment by sarwara on Nov-15-2012
Very good one, I was having tough time on similar problem. You saved my day. Many Thanks...
Comment by ccourt on Aug-23-2012
I ported your code to WPF, but was not successful in displaying the cell data, although the header names did appear. I am having problems with the statements related to Binding.Converter and Binding.ConverterParameter. I can compile only if I comment them out. Please help me understand why I am having this problem. Thank You.
Comment by asneuvon on May-11-2012
Simply perfect! Easy to implement and modify. You saved my day, week and possibly month.
Comment by Adarsha on Apr-08-2012
Thank you for an wonderful idea. I had a dynamic data collection, an Observable collection of IList objects had to be transposed as columns of the grid. I used your idea to bind all columns to same member, and having a converter which will return the items based on index passed as converter parameter. Excellent!! thanks a ton..
Comment by vino on May-26-2011
good technique, improve the code in short
Comment by Nick932 on Dec-18-2010
it is great that you post your code but if somebody can not read the obvious then he should not read the code....So i do not see the point of comments like this. Hich leads me to belive how good this can it be??? //dont allow empty column-name if (columnName.Equals(string.Empty)) {
Comment by Daniel Shewa on Sep-28-2010
It is a good technique, howevwer the convert back is not implemented. A user won't be able to edit the data using the datagrid. The is only useful for a readonly datagrid.
 Post your comment here
Your Name
Your Email
Comment
Post Comment

About      Terms      Contact