asp:Feature
LANGUAGES: C#
ASP.NET VERSIONS: 3.5
Columns & Rows:
Part I
Silverlight 2.0 DataGrid Properties
By Bilal Haidar
There is a need in every database-driven application to display data to end-users in the form of rows and columns that mimic the Excel sheets with which most end-users are familiar. Fortunately for us, Silverlight provides a rich and robust DataGrid control.
The Silverlight team at Microsoft issued the first release of the DataGrid in October 2008. This release had so many issues the team was forced to release an updated version in December 2008. This is the most up-to-date release, and includes more than 30 bug fixes. To read more about that latest release, visit the Silverlight 2 DataGrid December 2008 Release blog post by Scott Morrison, the project manager of the Silverlight DataGrid (blogs.msdn.com/scmorris/archive/2008/12/19/silverlight-2-datagrid-december-2008-release.aspx).
Working with the Silverlight 2.0 DataGrid is not difficult; however, having a series of articles dissecting its details can be beneficial, so this is exactly what I intend to do in this series.
Introduction
This article is the first in a series that will tackle most of the features of the Silverlight 2.0 DataGrid. There are several sections to discuss and explain regarding the Silverlight 2.0 DataGrid, including an overview of the DataGrid properties, auto-generating columns, defining columns in XAML, defining columns at runtime, implementing master/detail features, paging and sorting, and editing/deleting/adding rows using the DataGrid.
Through the course of this article, you ll get an overview of the majority of the DataGrid properties that play an important role in configuring the DataGrid, like setting the column width and row color, and alternating colors, among other things.
References to Silverlight 2.0
This article assumes you have a fair knowledge of using Silverlight 2.0 especially data-binding features and is not intended as an introduction to Silverlight 2.0. If you feel you need more information on Silverlight 2.0, I recommend you check the official website at www.silverlight.net, where you ll find dozens of articles and videos to get you started. Another major resource for learning Silverlight 2.0 is www.silverlightshow.net; it focuses on delivering rich and comprehensive tutorials on Silverlight.
Additionally, you can download the Microsoft Silverlight 2.0 SDK documentation, which covers all the features of Silverlight (www.microsoft.com/Downloads/details.aspx?familyid=BCE7684A-507B-4FC6-BC99-6933CD690CAB&displaylang=en).
The Silverlight DataGrid
To start, let s create a new Visual Studio 2008 Silverlight application. The Silverlight Application template has been integrated into Visual Studio 2008. When creating the new application, make sure to select the Add a new ASP.NET Web project to the solution to host Silverlight option, as shown in Figure 1.

Figure 1: Silverlight configuration screen
Selecting this option will create for you an ASP.NET Web project that hosts the Silverlight application; this also provides more flexibility for you as a developer to make use of all the ASP.NET features to which you are already accustomed.
Before we start with the details of adding the DataGrid and exploring its properties, the final product will be something similar to what is shown in Figure 2.

Figure 2: DataGrid properties view
As you can see in this demonstration, the DataGrid is on top, with the major properties to be discussed shown as separate rectangles, each with a title representing the property title and the body representing the different values that the property can accept.
Adding a DataGrid to a User Control
To add a DataGrid to a Silverlight User Control, all you need to do is drag the DataGrid control from the Silverlight XAML Controls toolbox that is only available for Silverlight applications. You can only drag controls on to the XAML part of the User Control because the Design View is still read-only for Silverlight applications. The dragged DataGrid control is shown in Figure 3.
Figure 3: Silverlight DataGrid control
Adding the DataGrid as shown in Figure 3 adds to the User Control header the XAML namespace shown in Figure 4.
xmlns:data="clr-namespace:System.Windows.Controls;
assembly=System.Windows.Controls.Data"
Figure 4: DataGrid XAML namespace
This is to say that the DataGrid control is located in the System.Windows.Controls namespace that is part of the System.Windows.Controls.Data assembly. This is required, because the DataGrid is only available as part of the Silverlight 2.0 Software Development Kit (SDK).
Adding a DataGrid this way without configuring any properties yields default values for some of the major properties (see Figure 5).
Property Name | Default Value |
AutoGenerateColumns | TRUE |
CanUserReorderColumns | TRUE |
CanUserResizeColumns | TRUE |
CanUserSortColumns | TRUE |
MaxColumnWidth | double.PositiveInfinity |
MinColumnWidth | 20 |
RowDetailsVisiblityMode | DataGridRowDetailsVisibilityMode.VisibleWhenSelected |
RowHeight | 2 |
SelectionMode | DataGridSelectionMode.Extended |
HorizontalGridLinesThinkness | 1 |
ColumnHeaderHeight | 4 |
RowHeaderWidth | 4 |
Figure 5: Major DataGrid properties
Now that you know how to add a DataGrid, let s start building each property s UI and explain how to use it, as well as its effect on the DataGrid.
DataGrid Properties
In this section, the major DataGrid properties will be listed together with a detailed explanation of the UI used to present the property and the code-behind that puts the properties selected values into effect by applying them to the DataGrid.
The GridLinesVisibility Property
This property controls the display of the horizontal or vertical grid lines separating the inner cells of the DataGrid. It is of type DataGridLinesVisibility enumeration.
The XAML UI in Figure 6 shows a StackPanel control holding a TextBlock control as a title, together with a ListBox control listing all the available values the GridLinesVisibility property accepts.
SelectionChanged="lstboxGridLinesVisibility_SelectionChanged"
>
Figure 6: XAML UI of the GridLinesVisibility property
Acceptable Value(s). The GridLinesVisibility property is a Dependency property and can take any of the following values:
- Horizontal: Only horizontal grid lines are displayed.
- Vertical: Only vertical grid lines are displayed.
- None: The DataGrid is displayed without any grid lines.
Each of the above values is displayed as a TextBlock control inside the ListBox control.
Code-behind. The ListBox control listing the acceptable values of the GridLinesVisibility property defines an event handler for the SelectionChanged event (see Figure 7).
The event handler in Figure 7 starts by getting a reference to the TextBlock control representing the value selected in the ListBox control. After that, the GridLinesVisibility property is set on the DataGrid by casting the value in to a DataGridGridLinesVisibility enumeration. Based on the item selected, the DataGrid will behave accordingly.
private void lstboxGridLinesVisibility_SelectionChanged(
object sender, SelectionChangedEventArgs e)
{
TextBlock option =
e.AddedItems[0] as TextBlock;
if (option.Text.Equals(""))
return;
this.dgEmployees.GridLinesVisibility = (DataGridGridLinesVisibility)
Enum.Parse(typeof(DataGridGridLinesVisibility), option.Text, true);
}
Figure 7: Define an event handler for the SelectionChanged event of the GridLinesVisibility property
The HeadersVisibility Property
This property controls the display of column and row headers on the DataGrid control. You are likely familiar with the column headers; however, the row header is a new feature added to a DataGrid that shows an empty cell beside each row, and hence acts as a header for every row displayed in the DataGrid. This property is of type HeadersVisibility enumeration.
The XAML UI in Figure 8 shows a StackPanel control holding a TextBlock control as a title, together with a ListBox control listing all the available values the HeadersVisibility property accepts.
SelectionChanged="lstboxHeadersVisiblity_SelectionChanged">
Figure 8: XAML UI of the HeadersVisibility property
Acceptable Value(s). The HeadersVisibility property is a Dependency property and can take any of the following values:
Column: Only column headers are displayed.
Row: Only row headers are displayed.
All: Both column and row headers are displayed.
None: Both column and row headers are not displayed.
Each of the above values is displayed as a TextBlock control inside the ListBox control.
Code-behind. The ListBox control listing the acceptable values of the HeadersVisibility property defines an event handler for the SelectionChanged event (see Figure 9).
private void lstboxHeadersVisibility_SelectionChanged(
object sender, SelectionChangedEventArgs e)
{
TextBlock option =
e.AddedItems[0] as TextBlock;
if (option.Text.Equals(""))
return;
this.dgEmployees.HeadersVisibility = (DataGridHeadersVisibility)
Enum.Parse(typeof(DataGridHeadersVisibility), option.Text, true);
}
Figure 9: Define an event handler for the SelectionChanged event of the HeadersVisibility property
The event handler in Figure 9 starts by getting a reference to the TextBlock control representing the value selected in the ListBox control. After that, the HeadersVisibility property is set on the DataGrid by casting the value in to a DataGridHeadersVisibility enumeration. Based on the item selected, the DataGrid will behave accordingly.
The RowBackground Property
This property decides on the Brush that is used to paint the background color of rows in a DataGrid. It is of type Brush.
The XAML UI in Figure 10 shows a StackPanel control holding a TextBlock control as a title, together with a ListBox control listing some color names that will be used to change the row background colors for the DataGrid rows.
SelectionChanged="lstboxRowBackground_SelectionChanged">
Figure 10: XAML UI of the RowBackground property
Acceptable Value(s). The RowBackground property is a Dependency property and can take only values of type Brush.
Code-behind. The ListBox control listing some color names defines an event handler for the SelectionChanged event (see Figure 11).
private void lstboxRowBackground_SelectionChanged(
object sender, SelectionChangedEventArgs e)
{
TextBlock option = e.AddedItems[0] as TextBlock;
if (option.Text.Equals(""))
return;
this.dgEmployees.RowBackground =
(Brush)this.Resources[option.Text];
}
Figure 11: Define an event handler for the SelectionChanged event of the RowBackground property
The event handler in Figure 11 starts by getting a reference to the TextBlock control representing the color value selected in the ListBox control. Then the RowBackground property is set on the DataGrid by casting in to a Brush object a resource object that was already defined in the XAML. Based on the color selected, the DataGrid s row backgrounds will change accordingly.
The trick here is to define a set of color brushes in the XAML part of the User Control and place them as part of the User Control s resources:
Opacity=".8" /> Opacity=".8"
/> A separate SolidColorBrush is defined for every
color intended to be added. Once the colors are added as User Control
resources, they can be accessed in the code-behind by accessing the ResourceDictionary
using an indexer; in this case, the key name that was used to define the color
Brush in XAML. Once a resource item is retrieved, it is cast to its proper type
(in this case, Brush type). The FrozenColumnCount Property This property controls the number of columns the
user will not be able to scroll horizontally. In other words, the value of this
property determines the columns that will be frozen, and on which the
horizontal scrollbar will not act. The XAML UI in Figure 12 shows a StackPanel control
holding a TextBlock control as a title, together with a ListBox control listing
some integer values that will be used to control the FrozenColumnCount property
of the DataGrid.
SelectionChanged="lstboxFrozenColumnCount_SelectionChanged"> Figure 12: XAML UI of the FrozenColumnCount
property Acceptable
Value(s).The FrozenColumnCount property is a Dependency property and can
take only integer values. Specifying an integer value represents the number of
columns to freeze while scrolling with the horizontal scrollbars. To freeze the
first column, set the value to 1 . To freeze the second column, set the value
to 2 , thus freezing the first two columns at once. Code-behind.
The ListBox control listing some color names defines an event handler for
the SelectionChanged event (see Figure 13). private void lstboxFrozenColumnCount_SelectionChanged( object sender,
SelectionChangedEventArgs e) { TextBlock option =
e.AddedItems[0] as TextBlock; if
(option.Text.Equals("")) return;
this.dgEmployees.FrozenColumnCount =
option.Text.Equals("None") ? 0 : Int32.Parse(option.Text); } Figure 13: Define an event handler for the
SelectionChanged event of the FrozenColumnCount property The event handler in Figure 13 starts by getting a
reference to the TextBlock control representing the integer value selected in
the ListBox control. If the selected value was None , which is a special value
added to represent 0 columns frozen, the DataGrid is configured with a value
of 0 on the FrozenColumnCount, else the exact number selected in the ListBox
control is cast to an integer and assigned on the FrozenColumnCount property. The SelectionMode Property This property controls the selection of a single or
multiple rows in a DataGrid. In general, the DataGrid has two main selection
modes; either a single selection, which means only one row, can be selected at
once, or extended selection mode, which allows the selection of multiple rows.
This property is of type DataGridSelectionMode enumeration. The XAML UI in Figure 14 shows a StackPanel control
holding a TextBlock control as a title, together with two RadioButton controls
for each of the possible values that the SelectionMode property accepts.
Content="Single" Checked="rbtnSingle_Checked" GroupName="grSelectionMode"
/>
Content="Extended" Checked="rbtnSingle_Checked"
GroupName="grSelectionMode" /> Figure 14: XAML UI of the SelectionMode
Property Acceptable
Value(s). The SelectionMode property is a Dependency property and can take
either of the following values:
Single: A single row can be selected at a time.
Extended: Multiple rows can be selected at once. Each of the above values is displayed as a
RadioButton control. Code-behind. The
above two RadioButton controls define the same event handler for the Checked
event. Checking either of these two controls triggers the Checked event. To
force only one of the RadioButtons to be checked at a time, you must add the
GroupName to both RadioButtons and make sure they have the same group name, and
thus only one RadioButton in a single group can be checked at a time. The
RadioButtons Checked event handler is defined in Figure 15. private void rbtnSingle_Checked(object sender, RoutedEventArgs e) { if
(this.rbtnSingle.IsChecked.Value)
this.dgEmployees.SelectionMode = DataGridSelectionMode.Single; if
(this.rbtnExtended.IsChecked.Value)
this.dgEmployees.SelectionMode = DataGridSelectionMode.Extended; } Figure 15: The RadioButtons Checked event
handler Based on what the user has selected, the
corresponding SelectionMode value is set on the DataGrid. The CanUserReorderColumns Property This property is of type Boolean; it allows or
prevents the user from selecting a column, then dragging and changing its order
among the other columns displayed in the DataGrid. When the property is set to
true , the user is allowed to drag a column and change its position on the DataGrid,
thus reordering the columns displayed. The XAML UI in Figure 16 shows a StackPanel control
holding a TextBlock control as a title, together with two RadioButton controls,
one for the true value and one for the false value that the CanUserReorderColumns
property accepts.
Content="True"
Checked="rbtnCanUserReorderColumns_Checked"
GroupName="grCanUserReorderColumns" />
Content="False"Checked="rbtnCanUserReorderColumns_Checked"
GroupName="grCanUserReorderColumns" /> Figure 16: XAML UI of the
CanUserReorderColumns property Acceptable
Value(s). The CanUserReorderColumns property is a Dependency property and
can take either a true or false value:
True: User is allowed to rearrange the DataGrid
columns.
False: Column rearrangement is not allowed in
the DataGrid. Each of the above values is displayed as a
RadioButton control. Code-behind.
The above two RadioButton controls define the same event handler for the
Checked event. Checking either of these two controls triggers the Checked
event. To force only one of the RadioButtons to be checked at a time, you must
add the GroupName to both RadioButtons and make sure they have the same group
name so only one RadioButton in a single group can be checked at a time. The
RadioButtons Checked event handler is defined in Figure 17. private void rbtnCanUserReorderColumns_Checked( object sender,
RoutedEventArgs e) { if
(this.rbtnCanUserReorderColumns.IsChecked.Value)
this.dgEmployees.CanUserReorderColumns = true; if
(this.rbtnCannotUserReorderColumns.IsChecked.Value)
this.dgEmployees.CanUserReorderColumns = false; } Figure 17: The RadioButtons Checked event
handler Based on what the user has selected, the
corresponding CanUserReorderColumns value is set on the DataGrid, thus allowing
or preventing a user from reordering the DataGrid columns. There are additional major properties that can be
manipulated on the DataGrid control. The code download accompanying this
article explores additional important properties; take some time to explore how
they are implemented. I also suggest you visit bhaidar.net/SilverlightDataGrid/GridProperties.aspx
to browse a live sample and play around with all the major DataGrid properties. Conclusion This article is the first in a series covering the
Silverlight 2.0 DataGrid control. This installment provides an overview of the
DataGrid properties and how they can be used to configure the behavior of the
DataGrid. Source code accompanying this article is available for download.
Bilal Haidar ([email protected]) is a Microsoft MVP in
ASP.NET. He is an MCP, MCTS, MCPD, MCT, and Telerik MVP. He is a lead software
developer at CCC, a multinational construction company based in Athens, Greece.