WPF搜索文本高亮:忽略大小写匹配及代码优化求助
问题描述
- 需求:根据TextBox中输入的搜索文本,为TextBlock内的对应文本着色,匹配时忽略大小写。
- 现有问题:当前代码在搜索文本与目标文本大小写不一致时无法正常匹配;若强制忽略大小写匹配,会将匹配文本替换为搜索文本的大小写,丢失TextBlock原文本的大小写格式。
- 诉求:优化代码实现忽略大小写匹配且保留原文本大小写,同时提供代码通用优化建议。
现有代码
private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e) { var searchText = (sender as TextBox)?.Text; if (!string.IsNullOrEmpty(searchText) && TextBlock.Text.Contains(searchText)) { var splitText = Regex.Split(TextBlock.Text, searchText); TextBlock.Text = string.Empty; TextBlock.Inlines.Add(new Run { "Text" = splitText[0] }); for (var i = 1; i < splitText.Length; i++) { TextBlock.Inlines.Add(new Run { "Text" = searchText, "Foreground" = Brushes.Yellow }); TextBlock.Inlines.Add(new Run { "Text" = splitText[i] }); } } else { string normalText = TextBlock.Inlines.Aggregate(string.Empty, (current, line) => current + (line as Run)?.Text); TextBlock.Inlines.Clear(); TextBlock.Text = normalText; } }
优化后的代码
private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e) { var textBox = sender as TextBox; if (textBox == null) return; string searchText = textBox.Text.Trim(); string originalText = TextBlock.Text; // 提前保存原始文本,避免从Inlines拼接出错 TextBlock.Inlines.Clear(); if (string.IsNullOrWhiteSpace(searchText)) { // 搜索文本为空时,直接显示原始文本 TextBlock.Inlines.Add(new Run { Text = originalText }); return; } // 转义搜索文本中的正则特殊字符,避免语法错误 string escapedSearchText = Regex.Escape(searchText); // 忽略大小写匹配,捕获所有匹配的原文本片段 MatchCollection matches = Regex.Matches(originalText, escapedSearchText, RegexOptions.IgnoreCase); int currentIndex = 0; foreach (Match match in matches) { // 添加匹配前的普通文本 if (match.Index > currentIndex) { TextBlock.Inlines.Add(new Run { Text = originalText.Substring(currentIndex, match.Index - currentIndex) }); } // 添加高亮的匹配文本(保留原大小写) TextBlock.Inlines.Add(new Run { Text = originalText.Substring(match.Index, match.Length), Foreground = Brushes.Yellow }); currentIndex = match.Index + match.Length; } // 添加最后一段未匹配的文本 if (currentIndex < originalText.Length) { TextBlock.Inlines.Add(new Run { Text = originalText.Substring(currentIndex) }); } }
通用优化建议
- 避免TextBlock.Text与Inlines混用:设置TextBlock.Text会自动清除所有Inlines,混用极易导致逻辑混乱,统一通过Inlines管理文本内容更可靠。
- 严谨的空值与边界处理:用
string.IsNullOrWhiteSpace替代!string.IsNullOrEmpty,能覆盖空格等空白字符的情况;同时提前保存原始文本,避免从Inlines拼接时出现错误。 - 正则表达式安全与性能:对用户输入的搜索文本做
Regex.Escape处理,防止特殊字符(如*、+、?)导致正则语法错误;频繁匹配时可添加RegexOptions.Compiled提升性能。 - 事件防抖优化:TextChanged事件会随用户每一次输入触发,可通过
DispatcherTimer实现防抖(比如延迟300ms执行逻辑),减少不必要的UI更新,提升流畅度。 - 代码可读性提升:将重复逻辑提取为独立方法,比如提取
ResetTextBlockContent、HighlightMatchedText等方法,让事件处理代码更简洁易懂。
内容的提问来源于stack exchange,提问作者Easdev
相关产品推荐
相关产品推荐

