突出显示 WPF ListView 中的搜索文本






4.91/5 (19投票s)
突出显示 WPF ListView 中搜索文本的解决方案

引言
我编写这个程序是为了借鉴微软 Outlook 的搜索方式。想象一下,你在一个 WPF 应用程序中有一个 ListView
,并且正在搜索各个项目中的文本。高亮显示文本会很有用。此演示程序中使用的代码可以根据需要进行调整,并且高亮显示的文本是通过使用 TextBox
控件显示的。
背景
假设你具备 C# 和 WPF 的基本知识。此应用程序代替了 TextBlock
控件中的 Text 属性,使用 Inline 属性和 Run 类,通过它可以更改文本属性(例如 Foreground
、Background
、FontSize
等)。
Using the Code
创建一个 ListView
和 TextBlock
搜索。添加一个 TextBox
TextChanged
事件,以便在 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>
使用 TextChanged
事件查找 ListViewItem
中的所有项目,使用递归方法 FindListViewItem
。使用 VisualTreeHelper
类中的 GetChildrenCount
将获得子对象数量。
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));
}
}
...
如果 DependencyObject
类型是 ListViewItem
,则使用递归方法 HighlightText
,该方法在 ListViewItem
中查找 TextBlock
对象。
private void HighlightText(Object itx)
{
if (itx != null)
{
if (itx is TextBlock)
{
..
}
else
{
...
}
}
return;
}
else
{
...
}
}
}
如果对象是 TextBlock
类型,则创建一个新的 RegEx
实例。
(参数 RegExOptions.IgnoreCase
忽略大小写字母。)
插入括号,你将达到文本的分隔,该字段将包含搜索的文本。
regex = new Regex("(" + textboxsearch.Text + ")", RegexOptions.IgnoreCase);
TextBlock
中的文本将其划分为一个字符串数组,借助 RegEx.Split
。使用 Inlines.Clear
清除原始文本。
tb.Inlines.Clear();
再次在 foreach
循环中,创建将比较字段表达式与搜索词的文本,使用 RegEx.Match
。
foreach (var item in substrings)
{
if (regex.Match(item).Success)
…
如果相同,则使用 Run
类,创建新的 Inline 元素,添加文本,更改背景颜色,并使用 Inlines.Add
方法将文本添加到 TextBlock
。否则,只需添加文本。
Run runx = new Run(item);
runx.Background = Brushes.Red;
tb.Inlines.Add(item);
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);
}
}
现在我们可以启动项目并尝试搜索了。
结论
此应用程序在突出显示文本时不会创建任何特殊效果,但我认为它可以作为一种灵感。
希望对您有所帮助,感谢您的阅读。
历史
- 2010年8月20日:初始发布