The Silverlight 2 DataGrid is auto-sized by default. This means that if you put it in a Canvas or a StackPanel and don't specify a Height or Width, or a MaxHeight or MaxWidth, you will get a DataGrid that is sized to its contents.
Warning: This can be dangerous however if you are working with a large (1000+ item) collection as the ItemsSource. Since the DataGrid will grow to the size of its contents, and will create objects for each cell that it can show based on its height, it will literally create thousands of objects to display all of the data. As you can guess this has app performance implications so you should avoid the combination of an auto-sized DataGrid and a large amount of data to display. This isn't an issue of course if you specify a Height or MaxHeight for the DataGrid, or put it in a container such as a Grid that provides it with a size.
Since the default size for the DataGrid is auto you won't have write any code to get auto-sizing behavior, but if you do give the DataGrid a height or width, and then want to switch it back to auto-size at runtime, simply set that value to double.NaN which is WPF and Silverlight's way of having a FrameworkElement auto-size itself.
C#
dataGrid1.Height = double.NaN;
VB
DataGrid1.Height = Double.NaN
In addition to the DataGrid auto-sizing itself, 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 differetly. If you have ever worked with the Grid control, you might have noticed that the Width property of its ColumnDefinitions is not of type double, but rather a struct called GridLength. The reason for this is that unlike a FrameworkElement's Width or Height properties which only have the possible values of Auto or a numeric value, a ColumnDefinition's Width can be set to a numeric value, Auto, or Star. DataGridColumn.Width follows a similar pattern where instead of being of type double, it is of type DataGridLength.
The possible values for DataGridLenth are:
Setting these in XAML is straight forward other than that unfortunately just like GridLength, there is no Intellisense for the enum values since a number is a valid entry as well.
XAML
<data:DataGrid x:Name="dataGrid1" AutoGenerateColumns="False"> <data:DataGrid.Columns> <data:DataGridTextColumn Binding="{Binding}" Width="Auto" Header="Auto"/> <data:DataGridTextColumn Binding="{Binding}" Width="SizeToHeader" Header="Size to Header"/> <data:DataGridTextColumn Binding="{Binding}" Width="SizeToCells" Header="Size to Cells"/> <data:DataGridTextColumn Binding="{Binding}" Width="50" Header="Numeric"/> </data:DataGrid.Columns> </data:DataGrid>
If you were to run the code above and give it a data source it would look something like this:
As you can see, once you know the possible enum values, setting it in XAML is fairly simple, and the Beta 1 code of Width="100" just works. When you are working in code behind however things get slightly more tricky.
If you wanted to write code to do the same as above:
DataGrid dataGrid1 = new DataGrid(); dataGrid1.AutoGenerateColumns = false; DataGridTextColumn col1 = new DataGridTextColumn(); col1.Binding = new Binding(); col1.Width = DataGridLength.Auto; col1.Header = "Auto"; dataGrid1.Columns.Add(col1); DataGridTextColumn col2 = new DataGridTextColumn(); col2.Binding = new Binding(); col2.Width = DataGridLength.SizeToHeader; col2.Header = "Size to Header"; dataGrid1.Columns.Add(col2); DataGridTextColumn col3 = new DataGridTextColumn(); col3.Binding = new Binding(); col3.Width = DataGridLength.SizeToCells; col3.Header = "Size to Cells"; dataGrid1.Columns.Add(col3); DataGridTextColumn col4 = new DataGridTextColumn(); col4.Binding = new Binding(); col4.Width = new DataGridLength(50); col4.Header = "Numeric"; dataGrid1.Columns.Add(col4); dataGrid1.ItemsSource = "a b c d e f g h i j".Split(); LayoutRoot.Children.Add(dataGrid1);
Dim dataGrid1 As New DataGrid dataGrid1.AutoGenerateColumns = False Dim col1 As New DataGridTextColumn col1.Binding = New Binding col1.Width = DataGridLength.Auto col1.Header = "Auto" dataGrid1.Columns.Add(col1) Dim col2 As New DataGridTextColumn col2.Binding = New Binding col2.Width = DataGridLength.SizeToHeader col2.Header = "Size to Header" dataGrid1.Columns.Add(col2) Dim col3 = New DataGridTextColumn col3.Binding = New Binding col3.Width = DataGridLength.SizeToCells col3.Header = "Size to Cells" dataGrid1.Columns.Add(col3) Dim col4 = New DataGridTextColumn col4.Binding = New Binding col4.Width = New DataGridLength(50) col4.Header = "Numeric" dataGrid1.Columns.Add(col4) dataGrid1.ItemsSource = "a b c d e f g h i j".Split() LayoutRoot.Children.Add(dataGrid1)
The interesting line above is where the Numeric column's width is set to 50. There are two ways to do this. If you are working with doubles, you can create a new GridLength that takes a double in its constructor. This is the most common and the easiest way to do it. If however you are working with strings such as a value in a TextBox, you can use the ConvertFrom method on DataGridLengthConverter which takes an object and returns a GridLength.