ComponentOne DataGrid for WPF and Silverlight
DataGrid for WPF and Silverlight Overview / DataGrid Features / Custom Rows / Customizing Row Cell Content
In This Topic
    Customizing Row Cell Content
    In This Topic

    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:
    Visual Basic
    Copy Code
    Imports C1.WPF.DataGrid
    Public Class DataGridFilterRow
       Inherits DataGridRow
    End Class
    

     

    C#
    Copy Code
    using C1.WPF.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:

    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:

    Visual Basic
    Copy Code
    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#
    Copy Code
    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:
      Visual Basic
      Copy Code
      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#
      Copy Code
      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:

      Visual Basic
      Copy Code
      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#
      Copy Code
      protected override void UnbindCellContent(FrameworkElement cellContent, DataGridColumn column)
      {
          var filterTextBox = (C1SearchBox)cellContent;
          filterTextBox.TextChanged -= new EventHandler<TextChangedEventArgs>(filterTextBox_TextChanged);
      }