Silvelight Datagrid Auto Sizing

When you use the DataGrid control in Silverlight and fill data from a data source using direct data binding, the DataGrid is auto-sized. That means, if a DataGrid is placed on a container such as a Canvas or a StackPanel and the Height or Width, or the MaxHeight or MaxWidth are not specified, it will be sized to the contents of the container control.

DataGrid can be auto-sized at runtime, by setting the height/width values to double.NaN, which is WPF and Silverlight's way of having a FrameworkElement auto-size itself.

DataGrid1.Height = double.NaN;

Further Columns and Rows are also auto-sized by default.  Like the DataGrid, rows are auto-sized in the same manner by setting the value to double.NaN while columns on the other hand are done slightly differently.  DataGridColumn.Width follows a similar pattern where instead of being of type double, it is of type DataGridLength.

The possible values for DataGridLenth are:

  • Auto: This auto-sizes the column or row to grow to the size of the largest header or cell.  It is effectively a combination of the other two auto-size modes.
  • SizeToHeader: This auto-sizes the column or row to grow to the size of the header.  This will ignore the contents of the cells when determining its size and will not change unless the size of the header changes.
  • SizeToCells: This auto-sizes the column or row to grow to the size of the largest visible cell.  It will ignore the header cell in this calculation.  As you scroll when a new larger cell is encountered that this value increases.  It will however not decrease once that item is scrolled out of view.
  • Numeric: Simply a numeric value such as 100.

This is how you can set the widht of a DataGrid columns at design time in XAML.

Setting DataGridColumn.Width in XAML

<data:DataGrid Name="DataGrid1" AutoGenerateColumns="False" ItemsSource="1234567890">
<data:DataGridTextColumn Binding="{Binding}" Width="100" Header
<data:DataGridTextColumn Binding="{Binding}" Width="Auto" Header
<data:DataGridTextColumn Binding="{Binding}" Width="SizeToHeader" Header
="Size to Header"/>
<data:DataGridTextColumn Binding="{Binding}" Width="SizeToCells" Header
="Size to Cells"/>

Same can be done at runtime as below:

DataGrid DataGrid1 = new DataGrid
DataGrid1.AutoGenerateColumns = false

DataGridTextColumn col1 = new DataGridTextColumn
col1.Binding = new Binding
col1.Width = new DataGridLength
col1.Header = "Fixed"
DataGridTextColumn col2 = new DataGridTextColumn
col2.Binding = new Binding
col2.Width = DataGridLength
col2.Header = "Size to Header"
DataGridTextColumn col3 = new DataGridTextColumn
col3.Binding = new Binding
col3.Width = DataGridLength
col3.Header = "Size to Cells"
DataGridTextColumn col4 = new DataGridTextColumn
col4.Binding = new Binding
col4.Width = DataGridLength
col4.Header = "Auto"

DataGrid1.ItemsSource = "1 2 3 4 5 6 7 8 9 0"

Now if you run the application, you will see the DataGrid is not sized to its container control anymore. The output will look like as below.


By using the same approach, you may also format a DataGrid columns the way you want.