在DBGrid中突出显示特定文本

3

我正在执行一个查询,并在dbgrid中显示返回的数据。

我想要突出显示与搜索条件匹配的项目。类似于:

搜索关键词: "test"

在DBGrid中,返回的数据如下。

ID     Return
1      This is a **test**
2      **Test**ing

这里的目标无疑是查询数据。但是如何在DBGrid中突出显示特定的文本呢?

重要提示:只有文本的特定部分应该被突出显示。

注意:所提供的信息是为了说明清楚,不一定与实际情况完全对应。


您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Ken White
2
理论上,你可以通过将Default Drawing设置为false,并使用OnDrawColumnCell和/或OnDrawDataCell事件自己绘制单元格来实现,但这需要在非常底层上进行相当多的工作。网格本身无法做到这一点。 - Dsm
DevExpress的GridView组件可以直接做到这一点,但它的价格不便宜。 - GuidoG
感谢@KenWhite的回答。但我的目标是解决问题,而不一定要购买组件,可以是免费软件或像ValMarinov那样的智能答案。无论如何,我删除了文本中与主题无关的部分;) - Marcoscdoni
1个回答

6

这个过程在 DbGrid 中突出显示“FilterText”。

procedure HighlightCellText(AGrid :TDbGrid; const ARect : TRect; AColumn : TColumn;  FilterText : string; AState:TGridDrawState ;
  BkColor : TColor = clYellow; SelectedBkColor : TColor = clGray);
var
  HlRect : TRect;
  Position : Integer;
  HlText, FilterColName,DisplayText: string;
  i, offset : Integer;
begin
   DisplayText := Acolumn.Field.AsString;
   Position := Pos(AnsiLowerCase(FilterText), AnsiLowerCase(DisplayText){  AnsiLowerCase(AColumn.DisplayText)});
   if Position > 0 then
   begin
     // set highlight area
     case AColumn.Alignment of
       taLeftJustify:  HlRect.Left := ARect.Left + AGrid.Canvas.TextWidth(Copy(DisplayText, 1, Position-1)) + 1;
       taRightJustify: begin
         Offset := AGrid.Canvas.TextWidth(Copy(DisplayText, 1,1)) - 1;
         HlRect.Left :=  (ARect.Right - AGrid.Canvas.TextWidth(DisplayText)-offset) + AGrid.Canvas.TextWidth(Copy(DisplayText, 1, Position-1));
       end;
       taCenter: begin
         Offset := ((ARect.Right - ARect.Left) div 2) - (AGrid.Canvas.TextWidth(DisplayText) div 2) - (AGrid.Canvas.TextWidth(Copy(DisplayText, 1,1)) - 2);

         HlRect.Left := (ARect.Right - AGrid.Canvas.TextWidth(DisplayText)- offset) + AGrid.Canvas.TextWidth(Copy(DisplayText, 1, Position-1));
       end;
     end;

     HlRect.Top := ARect.Top + 1;
     HlRect.Right := HlRect.Left +AGrid.Canvas.TextWidth(Copy(DisplayText, Position, Length(FilterText))) + 1 ;
     HlRect.Bottom := ARect.Bottom - 1;

     //check for  limit of the cell
     if HlRect.Right > ARect.Right then
       HlRect.Right := ARect.Right;

     // setup the color and draw the rectangle in a width of the matching text
     if gdSelected in AState then
       AGrid.Canvas.Brush.Color := SelectedBkColor
     else
       AGrid.Canvas.Brush.Color := BkColor;

     AGrid.Canvas.FillRect(HlRect);

     HlText := Copy(DisplayText,Position, Length(FilterText));
     AGrid.Canvas.TextRect(HlRect,HlRect.Left + 1,HlRect.Top + 1, HlText);
   end;
end;

在DbGrid.OnDrawColumnCell事件中使用:

例如,高亮显示文本为“ro”。

procedure TForm6.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
 begin
   HighlightCellText(TDBGrid(Sender),Rect, Column,'ro',State);
end;

结果:

结果:

enter image description here

编辑:

一个小演示


1
你能演示一下如何使用它吗?用户在编辑控件中键入搜索短语,网格突出显示该短语(而不滚动网格)。我唯一能想到的方法是使整个网格无效,这会导致一些难看的闪烁。 - Ken White
非常感谢Val Marinov!给定的方法完美地运行,没有任何问题。 - Marcoscdoni
@KenWhite 好的。这是演示。够了吗?:https://www.youtube.com/watch?v=pGKSDT5eSPA&feature=youtu.be - Val Marinov
是的。 :-) 做得非常好。我需要用真实数据(比网格中可以显示的更多列、更多行)来测试闪烁问题,但它似乎运行良好。谢谢。 :-) - Ken White

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接