WinForm中如何在ObjectListView中实现多文本搜索与高亮?
ObjectListView多文本多颜色高亮实现方案
针对你需要同时使用6个不同文本、对应不同颜色的高亮需求,这里提供三种可行的实现方案:
方案一:自定义复合高亮渲染器(推荐)
继承HighLightTextRenderer,内部维护多组高亮规则,重绘时依次处理所有规则实现叠加高亮:
public class MultiHighlightRenderer : HighLightTextRenderer { // 存储高亮文本与对应颜色的规则列表 public List<(string TargetText, Color HighlightColor)> HighlightRules { get; } = new(); protected override void DrawText(Graphics g, string text, Rectangle r, StringFormat sf, Brush foregroundBrush) { // 先绘制原始文本作为底色 base.DrawText(g, text, r, sf, foregroundBrush); foreach (var rule in HighlightRules) { if (string.IsNullOrWhiteSpace(rule.TargetText)) continue; // 遍历所有匹配的文本位置 int matchIndex = 0; while ((matchIndex = text.IndexOf(rule.TargetText, matchIndex, StringComparison.OrdinalIgnoreCase)) != -1) { // 计算高亮区域的尺寸和位置 var preTextSize = g.MeasureString(text.Substring(0, matchIndex), Font); var highlightTextSize = g.MeasureString(rule.TargetText, Font); var highlightRect = new Rectangle( r.X + (int)preTextSize.Width, r.Y, (int)highlightTextSize.Width, r.Height); // 绘制高亮背景 using var highlightBrush = new SolidBrush(rule.HighlightColor); g.FillRectangle(highlightBrush, highlightRect); // 重新绘制高亮区域的文本,保证文字清晰 using var textBrush = new SolidBrush(ForeColor); g.DrawString(rule.TargetText, Font, textBrush, highlightRect, sf); matchIndex += rule.TargetText.Length; } } } }
使用方式
实例化渲染器并添加所有高亮规则,设置为ObjectListView的默认渲染器:
var multiRenderer = new MultiHighlightRenderer(); multiRenderer.HighlightRules.Add(("用户ID", Color.LightYellow)); multiRenderer.HighlightRules.Add(("订单号", Color.LightBlue)); multiRenderer.HighlightRules.Add(("已完成", Color.LightGreen)); // 继续添加剩余3组规则 yourObjectListView.DefaultRenderer = multiRenderer;
方案二:按列分配独立渲染器
如果6组高亮规则分别对应不同列,可直接给每列单独设置HighLightTextRenderer:
// 为第一列设置高亮规则 var col1Renderer = new HighLightTextRenderer(); col1Renderer.HighlightText = "关键词1"; col1Renderer.HighlightBackColor = Color.Yellow; yourObjectListView.GetColumn(0).Renderer = col1Renderer; // 为第二列设置高亮规则 var col2Renderer = new HighLightTextRenderer(); col2Renderer.HighlightText = "关键词2"; col2Renderer.HighlightBackColor = Color.LightBlue; yourObjectListView.GetColumn(1).Renderer = col2Renderer; // 以此类推,为剩余4列配置对应渲染器
方案三:通过CellFormatting事件实现
利用ObjectListView的CellFormatting事件,在单元格格式化时手动处理多文本高亮,无需修改渲染器类:
// 订阅事件 yourObjectListView.CellFormatting += YourObjectListView_CellFormatting; // 事件处理逻辑 private void YourObjectListView_CellFormatting(object sender, ListViewCellFormattingEventArgs e) { // 指定需要处理的列(示例为第0列,可根据需求调整) if (e.ColumnIndex != 0) return; var cellText = e.SubItem.Text; if (string.IsNullOrWhiteSpace(cellText)) return; // 重置单元格默认格式 e.SubItem.Font = yourObjectListView.Font; e.SubItem.ForeColor = yourObjectListView.ForeColor; e.SubItem.BackColor = yourObjectListView.BackColor; // 定义所有高亮规则 var highlightRules = new List<(string Text, Color BackColor)> { ("待支付", Color.Orange), ("已取消", Color.LightGray), ("已退款", Color.Pink), // 添加剩余3组规则 }; // 使用RichTextBox生成带格式的文本 using var rtBox = new RichTextBox(); rtBox.Text = cellText; rtBox.SelectAll(); rtBox.SelectionFont = yourObjectListView.Font; rtBox.SelectionColor = yourObjectListView.ForeColor; foreach (var rule in highlightRules) { int startIndex = 0; while ((startIndex = cellText.IndexOf(rule.Text, startIndex, StringComparison.OrdinalIgnoreCase)) != -1) { rtBox.Select(startIndex, rule.Text.Length); rtBox.SelectionBackColor = rule.BackColor; startIndex += rule.Text.Length; } } // 将富文本格式赋值给单元格 e.SubItem.Text = rtBox.Rtf; }
方案对比
- 自定义复合渲染器:封装性好、复用性强,适合同一列需要多文本高亮的场景,性能最优。
- 按列分配渲染器:配置简单,适合不同列对应不同高亮规则的场景,但同一列无法实现多文本高亮。
- CellFormatting事件:无需修改渲染器,灵活性最高,但数据量大时性能略逊于前两种方案。
内容的提问来源于stack exchange,提问作者Trường Thế
相关产品推荐
相关产品推荐

