In this post I would like to share with you a simple solution for searching and highlighting text in the WPFToolkit or WPF 4.0 DataGrid.
The Problem
Lets say for example that you have a DataGrid with several columns that may display text. Now you want to be able to search terms in these text parts. For example:
Proposed Solution
1. Create an attached property of type string called SearchTerm for attaching the data-grid with the search term provided by a TextBox (see images).
<TextBox x:Name="SearchBox" ... />
<tk:DataGrid local:SearchOperations.SearchTerm=
"{Binding ElementName=SearchBox, Path=Text}" ...>
The SearchTerm attached property is defined as Inherits, so it could be easily extracted from any cell within the grid.
2. Calculate each cell data against the search term, and give a visual feedback accordantly.
- An easy way is to attach each cell with a boolean property that will be set to true in case that there is a match, or false otherwise. Then create a cell style trigger that yields visual feedback based on this attached property value.
<Style x:Key="FirstNameCell" TargetType="{x:Type tk:DataGridCell}">
<Setter Property="local:SearchOperations.IsMatch">
<Setter.Value>
<MultiBinding Converter="{StaticResource SearchTermConverter}">
<Binding Path="FirstName" />
<Binding RelativeSource="{RelativeSource Self}"Path="(local:SearchOperations.SearchTerm)" />
</MultiBinding>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="local:SearchOperations.IsMatch" Value="True">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="#FF84FF7A" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
To set the IsMatch attached property with the correct value, I’ve bound it with a multi-binding expression composed of two binding expressions using a multi-value converter:
- The value represented by the cell
- The search term attached property
- The Multi-value converter check if match exist
public class SearchTermConverter : IMultiValueConverter
{
#region IMultiValueConverter Members
public object Convert(object[] values, Type targetType,
object parameter, CultureInfo culture)
{
var stringValue = values[0] == null ? string.Empty : values[0].ToString();
var searchTerm = values[1] as string;
return !string.IsNullOrEmpty(searchTerm) &&
!string.IsNullOrEmpty(stringValue) &&
stringValue.ToLower().Contains(searchTerm.ToLower());
}
...
#endregion
}
Now that we’ve extended the WPF data-grid control with extra SearchTerm and IsMatch properties we can search terms in the grid and provide visual feedbacks using styles.
You can download the code from here, and the WPFToolkit from here.