You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 15:03:21