Ver Mensaje Individual
  #1  
Antiguo 11-12-2015
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Reputación: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
TDBGrid, pintar/negrita texto celda parcial

Saludos

Estoy usando Delphi 2010, y el efecto que quiero lograr es poner en negrita (o colorear, en fin cualquier forma de resaltar texto me vendria bien) parte del contenido de una celda de un TDBGrid; la idea es lanzar una busqueda y resaltar todas los campos en donde coincide el texto buscado

Ejemplo: busco "agustin" entonces el DBGrid deberia mostrar

Código Delphi [-]
Nombre             Direccion                           ...
Agustin    Calle agustincito        ...

Al grid ademas le asigno estas propiedades:

Código Delphi [-]
DefaultDrawing := False 
Options := [dgTitles, dgIndicator, dgColumnResize, dgColLines, dgRowLines, dgTabs, dgRowSelect,
    dgAlwaysShowSelection, dgCancelOnExit, dgTitleClick, dgTitleHotTrack];

Lo que hice fue agregar un manejador al evento OnDrawColumnCell, este es el codigo:

Código Delphi [-]
TForm1.(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
var
  R: TRect;
  LCanvas: TCanvas;
  LFieldValue, LChar: string;
  I: Integer;
begin
  LCanvas := TDBGrid(Sender).Canvas;
  if DataCol in [0 .. 1] then
  begin
    LFieldValue := Column.Field.AsString;

    if not AnsiContainsText(LFieldValue, FSearchString) then
    begin
      LCanvas.Font.Style := LCanvas.Font.Style - [fsBold];
      TDBGrid(Sender).DefaultDrawColumnCell(Rect, DataCol, Column, State);
      Exit;
    end;

    R := Rect;
    for I := 1 to Length(LFieldValue) do
    begin
      LChar := LFieldValue[i];

      // desplazamiento del rectangulo
      if I > 1 then
        R.Left := R.Left + LCanvas.TextWidth(LChar);

      if (Length(FSearchString) >= I) and (AnsiSameText(LChar, FSearchString[i])) then
        LCanvas.Font.Style := LCanvas.Font.Style + [fsBold]
      else
        LCanvas.Font.Style := LCanvas.Font.Style - [fsBold];

      // dibujar cada caracter
      LCanvas.TextRect(R, LChar);
    end;
  end
  else
  begin
    LCanvas.Font.Style := LCanvas.Font.Style - [fsBold];
    TDBGrid(Sender).DefaultDrawColumnCell(Rect, DataCol, Column, State);
  end;
end;

Basicamente voy pintando caracter a caracter, en negrita o no, segun se vaya cumpliendo la coincidencia parcial

Pero me queda "feo" el texto, asi es como sale:



Curiosamente para numeros parece "ir bien", pero el texto sale horrible

Alguien puede arrojar algo del luz?

PD: Otras alternativas de haberlas, encantado de oirlas; por ejemplo, si con otro control VCL es facil lograr el efecto, aunque no sea data-aware, podria escribir la parte de llenar el contenido (un ListView por ejemplo). En lo posible prefiero no usar componentes de terceros
Responder Con Cita