Search code examples
delphidelphi-xe7

Highlight specific text in DBGrid


I'm performing a query and displaying returned data in dbgrid.

I would like to highlight the items matching the search criteria. Something like:

Search by : "test"

In DBGrid, returned data would be .

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

The goal here is no doubt about querying data. But how to highlight specific text in DBGrid?

Important: only the specific part of the text should be highlighted.

NOTE: The information presented is to make it clear, not corresponding exactly to reality.


Solution

  • This procedure highlight `FilterText' in DbGrid

    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;
    

    Use it in DbGrid.OnDrawColumnCell event :

    For example highlight text is "ro".

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

    The result :

    enter image description here

    Edit :

    A litle demo