In this article, we will look into some of the aspects of Silverlight Datagrid as
a) Create a custom entity and bind to DataGrid through code using AutoGenerated Column On
Introduction
Datagrid control is a very old and well known control in the dotnet community and every presentation framework supported by microsoft so far has this component.
Silverlight is also not an exception and in this article, we will address, how to use datagrid control in silverlight.
What will we cover in this article?
- Create a custom entity and bind to DataGrid through code using AutoGenerated Column On
- DataGrid binding by manually defining columns using Column Collection
- Paging in DataGrid using DataPager and PagedCollectionView class
- Displaying images in DataGrid
1. Create a custom entity and bind to DataGrid through code using AutoGenerated Column On (Attached Example 1)
Drag and drop a Datagrid control into the Xaml from the toolbox and name it as "myDataGrid"
<sdk:DataGrid
AutoGenerateColumns="True"
HeadersVisibility="All"
RowBackground="YellowGreen"
AlternatingRowBackground="Beige"
ColumnWidth="85"
RowHeight="30"
Name="myDataGrid" />
Let us create an Employee Entity as under
public class EmployeeEntity
{
public int EmployeeId { get; set; }
public string EmployeeName { get; set; }
public int Age { get; set; }
public decimal Salary { get; set; }
public DateTime DOJ { get; set; }
public bool IsInProject { get; set; }
}
Now,let us populate the EmployeeEntity as under
private void GetPersonData()
{
for (int i = 1; i <= 10; i++)
{
personEntities.Add(new EmployeeEntity
{
EmployeeId = i
,
EmployeeName = string.Concat("Employee ", i)
,
Age = 20 + i
,
Salary = 5000 + i * 10
,
DOJ = DateTime.Now.AddYears(-10).AddYears(i)
,
IsInProject = i % 2 == 0 ? true : false
});
}
}
And assign the collection to the Data Grid in the Page Loaded event as under
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
//Bind to grid
myDataGrid.ItemsSource = personEntities;
}
The output is as under

2. DataGrid binding by manually defining columns using Column Collection (Attached Example 2)
We define a manual binding when we know in advance as exactly what columns to be displayed, any customizations are needed or not on the columns etc.We can achieve this by using Columns Collection
about which we will talk here
The Columns Collection helps us to manage the DataGrid's column order, their appearance as well as the controls that will be helpful in publishing data in the cells.
It has the following column types
- DataGridTextColumn : It uses a TextBlock to display the data and a TextBox control to edit data.
- DataGridCheckBoxColumn : It uses a read-only CheckBox to display a boolean or nullable boolean value and a normal CheckBox to edit the existing value.
- DataGridTemplateColumn : Any other kind of controls that the application may need to display the data in it's column e.g. image
So with this kind of knowledge, let us modify our existing applications xaml code as under
<sdk:DataGrid
AutoGenerateColumns="False"
RowBackground="YellowGreen"
AlternatingRowBackground="Beige"
ColumnWidth="85"
RowHeight="30"
Name="myDataGrid">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Header="Employee Id" Width="100" Binding="{Binding EmployeeId}" />
<sdk:DataGridTextColumn Header="Employee Name" Width="200" Binding="{Binding EmployeeName}" />
<sdk:DataGridTextColumn Header="Employee Age" Width="150" Binding="{Binding Age}" />
<sdk:DataGridTextColumn Header="Employee Salary" Width="150" Binding="{Binding Salary}" />
<sdk:DataGridTextColumn Header="Date Of Joining" Width="200" Binding="{Binding DOJ}" />
<sdk:DataGridCheckBoxColumn Header="Allocated in Project" Width="130" Binding="{Binding IsInProject}" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
Let the remaining code be as it is and run the application to get the below output

Now,our DOJ field has both the date and time field. Suppose we want to display only the date field. In that case we will use a template column and a value convertor to accomplish the task. (Well there can be other ways also to achieve the same).So with this view in mind, let us create a class say "DateConvertor" that will implement the IValueConvertor interface as under
public class DateConvertor : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return ((DateTime)value).ToString("MM/dd/yyyy");
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return DateTime.ParseExact(value.ToString(), "ddMMyyyy", CultureInfo.InvariantCulture);
}
#endregion
}
So, we have added the conversion logic in the Convert and ConvertBack methods of the IValueConverter interface.
Coming to the xaml code, first add a local xmlns
xmlns:local="clr-namespace:SilverlightApplication1"
Next add the converter to the UserControl as a static resource.
<UserControl.Resources>
<local:DateConvertor x:Key="CustomDateConverter" />
</UserControl.Resources>
Ultimately,invoke the converter from the TextBlock's binding in the DataGridTemplateColumn as shown below
<sdk:DataGridTemplateColumn Header="Formatted DOJ using Convertor" Width="200">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding DOJ, Converter={StaticResource CustomDateConverter}}"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
The entire xaml code looks as under
<UserControl x:Class="SilverlightApplication1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:local="clr-namespace:SilverlightApplication1"
Loaded="UserControl_Loaded">
<UserControl.Resources>
<local:DateConvertor x:Key="CustomDateConverter" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<sdk:DataGrid
AutoGenerateColumns="False"
RowBackground="YellowGreen"
AlternatingRowBackground="Beige"
ColumnWidth="85"
RowHeight="30"
Name="myDataGrid">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Header="Employee Id" Width="100" Binding="{Binding EmployeeId}" />
<sdk:DataGridTextColumn Header="Employee Name" Width="200" Binding="{Binding EmployeeName}" />
<sdk:DataGridTextColumn Header="Employee Age" Width="150" Binding="{Binding Age}" />
<sdk:DataGridTextColumn Header="Employee Salary" Width="150" Binding="{Binding Salary}" />
<sdk:DataGridTextColumn Header="Date Of Joining" Width="200" Binding="{Binding DOJ}" />
<sdk:DataGridCheckBoxColumn Header="Allocated in Project" Width="130" Binding="{Binding IsInProject}" />
<sdk:DataGridTemplateColumn Header="Formatted DOJ using Convertor" Width="200">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding DOJ, Converter={StaticResource CustomDateConverter}}"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</Grid>
</UserControl>
with the output being

3. Paging in DataGrid using DataPager and PagedCollectionView class (Attached Example 3)
While the data size grows it becomes necessary to split data across pages- a concept that is call as Paging.We will use the PagedCollectionView class for doing paging along with the DataPager control.
The PagedCollectionView class splits data into multiple pages as per the static row number provided per page.In silverlight,the DataPager control gives a user friendly interface that is highly customizable for paging through a data collection that can be any IEnumerable collection e.g. PagedCollectionView here. It can also be bind to the ItemsSource of the DataGrid.
So in the xaml, let us add a DataPager control as under
<sdk:DataPager x:Name="pagerEmployee"
PageSize="5"
DisplayMode="FirstLastPreviousNext"
NumericButtonCount="1"
Source="{Binding Path=ItemSource,ElementName=myDataGrid}">
</sdk:DataPager>
Here we will display 5 rows per page. The source of the DataPager is the DataGrid ("myDataGrid")
In the Page Load event, let us write the below piece of code
PagedCollectionView pcView = new PagedCollectionView(personEntities);
//Bind to grid
myDataGrid.ItemsSource = pcView;
//Bind to data pager
pagerEmployee.Source = pcView;
//Also works
//pagerEmployee.Source = myDataGrid.ItemsSource;

4.Displaying images in DataGrid (Attached Example 4)
In this example we will pass the EmployeeId to ImageConvertor class that implements the IValueConverter and in the Convert method by tracking even/odd EmployeeId, we will load some sample images.The convertor class is as under
public class ImageConvertor : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var employeeObject = value as EmployeeEntity;
Image empImg = new Image();
if(employeeObject.EmployeeId % 2 ==0)
{
empImg.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri("1.jpg", UriKind.Relative));
}
else
{
empImg.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri("2.jpg", UriKind.Relative));
}
return empImg;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
And the xaml is as under
<sdk:DataGridTemplateColumn
Width="Auto" Header="Employee Image">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl
Content="{Binding Converter={StaticResource EmployeeImages}}"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch" />
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
Output

Conclusion
This article shows some of the operations that a developer may need in their day to day operation while working with Silverlight DataGrid controls.Hope you like this and will be useful.