This topic explains how to customize cell content. For example, suppose you wanted to build a filter row. You could create a grid where the first row has a TextBox in each cell and when you type on it the grid is filtered by the typed text as in the following image:
Adding a Class File
You would need to add a new class file where the custom row will be written. For example, complete the following steps to add a new class file:
1. Navigate to the Solution Explorer, right-click the project name and select Add│New Item.
2. In the Add New Item dialog box choose Class in the list of available templates.
3. Name the class, for example "DataGridFilterRow", and click the Add button to add the class to the project.
4. Update the class so it appears similar to the following:
Imports C1.Silverlight.DataGrid
Public Class DataGridFilterRow
Inherits DataGridRow
End Class
•C#
using C1.Silverlight.DataGrid;
public class DataGridFilterRow : DataGridRow
{
}
This will update the class to inherit from DataGridRow. Once the file is created it must inherit from DataGridRow.
Once you've added the class, you can use it to implement filtering in the grid.
Overriding Methods
The methods you would need to override to specify the cell content of custom row are very similar to those exposed in custom columns. To implement custom cell content you'd need to override the following methods:
• HasCellPresenter: Determines whether a cell should exist for this row and the specified column.
• GetCellContentRecyclingKey: Key used to store the cell content for future reuse in a shared pool. Rows returning the same RecyclingKey can share the same cell content instances.
• CreateCellContent: Creates a visual element that will be used to display information inside a cell in this column.
• BindCellContent: Initializes the cell content presenter.
• UnbindCellContent: This method is called before the cell content is recycled.
In the filter row the HasCellPresenter method will return always true, because all columns will have a corresponding cell. In other scenarios like a summary row, only the columns where there is an aggregate function will have a cell.
The GetCellContentRecyclingKey method will return typeof(TextBox), which allows recycling the text boxes, and the CreateCellContent will create a new instance of it. Add the following code to
Protected Overrides Function GetCellContentRecyclingKey(column As DataGridColumn) As Object
Return GetType(TextBox)
End Function
Protected Overrides Function CreateCellContent(column As DataGridColumn) As FrameworkElement
Return New TextBox()
End Function
•C#
protected override object GetCellContentRecyclingKey(DataGridColumn column)
{
return typeof(TextBox);
}
protected override FrameworkElement CreateCellContent(DataGridColumn column)
{
return new TextBox();
}
Implementing Filtering
In the previous steps you added a TextBox in each cell, but these controls currently do not do anything; to implement filtering complete the following steps:
1. Add the following code to the BindCellContent method:
Protected Overrides Sub BindCellContent(cellContent As FrameworkElement, column As DataGridColumn)
Dim filterTextBox = DirectCast(cellContent, TextBox)
'If the column doesn't have a FilterMemberPath specified
'it won't allow entering text in the TextBox;
If String.IsNullOrEmpty(column.FilterMemberPath) Then
filterTextBox.IsEnabled = False
filterTextBox.Text = "Not available"
Else
filterTextBox.Text = ""
filterTextBox.IsEnabled = True
End If
' Handle TextChanged to apply the filter to the column.
filterTextBox.TextChanged += New EventHandler(Of TextChangedEventArgs)(filterTextBox_TextChanged)
End Sub
•C#
protected override void BindCellContent(FrameworkElement cellContent, DataGridColumn column)
{
var filterTextBox = (TextBox)cellContent;
//If the column doesn't have a FilterMemberPath specified
//it won't allow entering text in the TextBox;
if (string.IsNullOrEmpty(column.FilterMemberPath))
{
filterTextBox.IsEnabled = false;
filterTextBox.Text = "Not available";
}
else
{
filterTextBox.Text = "";
filterTextBox.IsEnabled = true;
}
// Handle TextChanged to apply the filter to the column.
filterTextBox.TextChanged += new EventHandler<TextChangedEventArgs>(filterTextBox_TextChanged);
}
2. In UnbindCellContent you must remove the text changed handler to avoid leaking memory:
Protected Overrides Sub UnbindCellContent(cellContent As FrameworkElement, column As DataGridColumn)
Dim filterTextBox = DirectCast(cellContent, C1SearchBox)
filterTextBox.TextChanged -= New EventHandler(Of TextChangedEventArgs)(filterTextBox_TextChanged)
End Sub
•C#
protected override void UnbindCellContent(FrameworkElement cellContent, DataGridColumn column)
{
var filterTextBox = (C1SearchBox)cellContent;
filterTextBox.TextChanged -= new EventHandler<TextChangedEventArgs>(filterTextBox_TextChanged);
}