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

WPF中如何在ListBox不同背景色下高亮文本特定部分

修改ListBox高亮逻辑:实现整行背景+特定文本高亮

现有代码仅能实现ListBox整行背景高亮,需要调整为整行背景设为指定颜色,同时高亮文本中的特定片段(比如对“Hello World to WPF”,整行浅蓝背景,“World”用其他颜色高亮),以下是原代码及修改方案:

原代码

private async void WriteHighlighttexts(ListBox Datalabel, Dictionary<long, List<string[]>> arraylog)
{
    Datalabel.Items.Clear();

    foreach (KeyValuePair<long, List<string[]>> pair in arraylog)
    {
        List<string[]> logwritehigh = pair.Value;

        // Set autoScroll to false before updating the content
        bool autoScroll = false;

        foreach (string[] pair2 in logwritehigh)
        {
            string Linecolour = pair2[0];
            await Task.Run(() =>
            {
                // Run the code in the background thread

                Dispatcher.Invoke(() =>
                {
                    // Append the line to the ListBox
                    ListBoxItem listBoxItem = new ListBoxItem();
                    listBoxItem.Content = pair2[1];
                    Datalabel.Items.Add(listBoxItem);

                    //// Ensure the text is fully updated before proceeding with highlighting
                    //Task.Delay(5).Wait();

                    // Highlight the entire line with the specified color
                    HighlightLine(listBoxItem, Linecolour);
                });
            });

            await Task.Delay(15);

            // Restore autoScroll to true after updating the content
            autoScroll = true;

            // Scroll to the end of the RichTextBox if autoScroll is enabled
            if (autoScroll)
            {
                Datalabel.ScrollIntoView(Datalabel.Items[Datalabel.Items.Count - 1]);
            }
        }
    }
}

private void HighlightLine(ListBoxItem listBoxItem, string color)
{
    System.Drawing.Color lineColor = ColorTranslator.FromHtml(color);
    SolidColorBrush brush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(lineColor.A, lineColor.R, lineColor.G, lineColor.B));

    listBoxItem.Background = brush;
}

修改方案

1. 调整数据结构传递高亮参数

原string[] pair2仅包含行背景色和文本内容,需要新增两个元素:要高亮的关键词、关键词高亮颜色,即pair2结构变为[行背景色, 文本内容, 高亮关键词, 关键词颜色]。

2. 用TextBlock替代纯字符串实现富文本

直接设置ListBoxItem.Content为字符串无法实现局部文本高亮,需改用TextBlock,通过Run元素拆分文本,给目标关键词单独设置样式。

3. 重写高亮逻辑,同时处理整行背景和局部文本

修改后的完整代码如下:

private async void WriteHighlighttexts(ListBox Datalabel, Dictionary<long, List<string[]>> arraylog)
{
    Datalabel.Items.Clear();

    foreach (KeyValuePair<long, List<string[]>> pair in arraylog)
    {
        List<string[]> logwritehigh = pair.Value;
        bool autoScroll = false;

        foreach (string[] pair2 in logwritehigh)
        {
            string lineBgColor = pair2[0];
            string textContent = pair2[1];
            string highlightKeyword = pair2[2]; // 新增:要高亮的关键词
            string keywordColor = pair2[3];     // 新增:关键词的高亮颜色

            await Task.Run(() =>
            {
                Dispatcher.Invoke(() =>
                {
                    // 创建TextBlock承载富文本
                    TextBlock textBlock = new TextBlock();
                    textBlock.TextWrapping = TextWrapping.Wrap; // 可选:开启自动换行

                    // 拆分文本,构建带高亮的内容
                    int keywordIndex = textContent.IndexOf(highlightKeyword, StringComparison.OrdinalIgnoreCase);
                    if (keywordIndex >= 0)
                    {
                        // 添加关键词前的普通文本
                        if (keywordIndex > 0)
                        {
                            textBlock.Inlines.Add(new Run(textContent.Substring(0, keywordIndex)));
                        }
                        // 添加高亮的关键词
                        Run highlightRun = new Run(highlightKeyword);
                        highlightRun.Foreground = GetSolidColorBrush(keywordColor);
                        textBlock.Inlines.Add(highlightRun);
                        // 添加关键词后的普通文本
                        if (keywordIndex + highlightKeyword.Length < textContent.Length)
                        {
                            textBlock.Inlines.Add(new Run(textContent.Substring(keywordIndex + highlightKeyword.Length)));
                        }
                    }
                    else
                    {
                        // 无匹配关键词时直接添加完整文本
                        textBlock.Inlines.Add(new Run(textContent));
                    }

                    // 创建ListBoxItem并设置内容和背景
                    ListBoxItem listBoxItem = new ListBoxItem();
                    listBoxItem.Content = textBlock;
                    listBoxItem.Background = GetSolidColorBrush(lineBgColor);
                    Datalabel.Items.Add(listBoxItem);
                });
            });

            await Task.Delay(15);
            autoScroll = true;

            if (autoScroll)
            {
                Datalabel.ScrollIntoView(Datalabel.Items[Datalabel.Items.Count - 1]);
            }
        }
    }
}

// 提取颜色转换逻辑为通用方法,减少冗余代码
private SolidColorBrush GetSolidColorBrush(string colorStr)
{
    System.Drawing.Color drawColor = ColorTranslator.FromHtml(colorStr);
    return new SolidColorBrush(System.Windows.Media.Color.FromArgb(drawColor.A, drawColor.R, drawColor.G, drawColor.B));
}

关键改动说明

  • 用TextBlock+Run的组合实现局部文本样式控制,替代原有的纯字符串内容。
  • 新增GetSolidColorBrush方法统一处理颜色转换逻辑,避免重复代码。
  • 文本拆分逻辑:定位关键词位置,分别添加普通文本和高亮Run;如需支持多个关键词,可扩展为循环查找所有匹配项。
  • 保留原有的异步更新和自动滚动逻辑,保证UI响应性。

使用示例

若arraylog中的string[]为["#ADD8E6", "Hello World to WPF", "World", "#FF0000"],则整行背景为浅蓝色,"World"文本显示为红色。


内容的提问来源于stack exchange,提问作者WDpad159

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 15:27:11