Introduction
I wrote this as an inspiration for how to search in Microsoft Outlook. Imagine that you have a ListView
in a WPF application and you are looking for a text in the individual items. It would be useful to highlight the text. The code used in this demo can be adjusted wherever it's appropriate and the highlighted text is displayed by using the TextBox
control.
Background
It is assumed you have basic knowledge of C# and WPF. This application is used instead of Text property in TextBlock
control, Inline property and class Run
through which we can change the text properties (such as Foreground
, Background
, FontSize
, etc.) .
Using the Code
Create a Listview
and TextBlock
search. Add a TextBox
TextChanged
event for an instant search in ListView
.
<DockPanel LastChildFill="True">
<StackPanel HorizontalAlignment="Left" DockPanel.Dock="Top">
<Label Name="labelSearch" Content="Search"/>
<TextBox Name="textboxsearch" Width="309"
TextChanged="textboxsearch_TextChanged"
>
</TextBox>
</StackPanel>
<ListView Name="listview" Width="310" DockPanel.Dock="Top"
HorizontalAlignment="Left" FontWeight="Bold" FontSize="16" AlternationCount="2"
ItemContainerStyle="{StaticResource AlternateItemStyle}">
<ListView.View>
<GridView>
<GridViewColumn Header="First Name"
DisplayMemberBinding="{Binding Path=FirstName}">
</GridViewColumn>
<GridViewColumn Header="Last Name"
DisplayMemberBinding="{Binding Path=LastName}">
</GridViewColumn
</GridView>
</ListView.View>
</ListView>
</DockPanel>
Use TextChanged
event to find all the items in ListViewItem
with the recursive method FindListViewItem
. GetChildrenCount
with VisualTreeHelper
class will bring the number children object.
private void textboxsearch_TextChanged(object sender, TextChangedEventArgs e)
{
{
FindListViewItem(listview);
}
}
public void FindListViewItem(DependencyObject obj)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
ListViewItem lv = obj as ListViewItem;
if (lv != null)
{
HighlightText(lv);
}
FindListViewItem(VisualTreeHelper.GetChild(obj as DependencyObject, i));
}
}
...
And if DependecyObject
type is ListViewItem
, use a recursive method HighlightText
which looks in ListViewItem
for TextBlock
objects.
private void HighlightText(Object itx)
{
if (itx != null)
{
if (itx is TextBlock)
{
..
}
else
{
...
}
}
return;
}
else
{
...
}
}
}
If the object is TextBlock
type, create a new instance RegEx
.
(Parameter RegExOptions.IgnoreCase
ignores uppercase and lowercase letters.)
Inserting brackets, you will reach the division of text into the field, which will include the searched text.
regex = new Regex("(" + textboxsearch.Text + ")", RegexOptions.IgnoreCase);
The text in the TextBlock
divides it into a string
array of assistance RegEx.Split
. Clear the original text with Inlines.Clear
.
tb.Inlines.Clear();
And again in the foreach
cycle, create the text that compares the expression of the field with the search terms with RegEx.Match
.
foreach (var item in substrings)
{
if (regex.Match(item).Success)
…
If identical, then use the Run
class, create new Inline element, add text, change the background color, and add text to TextBlock
with Inlines.Add
methods. Otherwise, just add text.
Run runx = new Run(item);
runx.Background = Brushes.Red;
tb.Inlines.Add(item);
The code to change text in the background in full:
foreach (var item in substrings)
{
if (regex.Match(item).Success)
{
Run runx = new Run(item);
runx.Background = Brushes.Red;
tb.Inlines.Add(runx);
}
else
{
tb.Inlines.Add(item);
}
}
Now we can start the project and try searching.
Conclusion
This application does not create any special effects when you highlight the text, but I think it can serve as an inspiration.
I hope you found it useful and thanks for reading.
History
- 20th August, 2010: Initial post