Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Colorear una fila seleccionada... (https://www.clubdelphi.com/foros/showthread.php?t=65065)

seb@ 18-11-2009 04:52:30

Colorear una fila seleccionada...
 
Hola foro!!!
Estoy buscando la manera de colorear una fila completa de un dbgrid, estuve buscando y no encontre nada.
El tema es el siguiente, tengo un dbgrid con una serie de informacion ahora cuando hago dbl click en una fila determinada que puede ser cualquiera ahi recien se tiene que colorear la misma, se puede hacer esto de alguna manera?

De antemano, Gracias!

gerardus 18-11-2009 09:45:27

Hola,

Mira los eventos OnDrawDataCell y OnDrawColumnCell del grid, Allí puedes colorear a tu gusto.
El problema es que vas a tener que guardar el estado de la fila en algun sitio (campo) porque las filas no se pintan cuando tu quieres sino cuando el grid lo decide.
O sea que tu clic debe cambiar el valor de algun campo en el dataset que hay detrás del grid para poder pintar luego segun al valor del campo.

p.e. añades un campo "estado" de tipo integer, que al hacer doble clic se cambie de zero a 1.

Código Delphi [-]
procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect; Field: TField; State: TGridDrawState);
begin
 // Si estado = 1, pinta en letra roja.
  if DBGrid1.Datasource.Dataset.FieldByName('Estado').AsInteger = 1 then
    DBGrid1.Canvas.Font.Color := clRed;
  DBGrid1.DefaultDrawDataCell(Rect, Field, State);
end;

Cordialmente,

Gerard.

Neftali [Germán.Estévez] 18-11-2009 09:59:40

Cita:

Empezado por seb@ (Mensaje 346861)
El tema es el siguiente, tengo un dbgrid con una serie de informacion ahora cuando hago dbl click en una fila determinada que puede ser cualquiera ahi recien se tiene que colorear la misma, se puede hacer esto de alguna manera?

Colorear las filas de un DBGrid es sencillo y si buscas en el foro encontrarás no pocos hilos al respecto, con código incluído.

Si he entendido bien lo que tú necesitas, el problema y lo complicado en tu caso, es que no quieres pintar filas segun un valor existente en el DBGrid, sino a medida que vas pulsando click en ellas.

Para eso lo único que se me ocurre es que al pulsar doble click sobre la fila modifiques el valor de ese registro (un campo interno llamado COLOREAR, por ejemplo) y lo actives (UPDATE a TRUE). No es necesario que ese campo esté visible si no lo necesitas. Ese mismo campo es el que debes utilizar para colorear las filas del DBGrid de la forma estandard utilizando el evento OnDrawColumn.

flystar 30-07-2010 22:39:02

Saludos
 
Ah que te refieres cuando dices que lo active???

Podrías ser mas específico, yo tengo el mismo problema no quiero depender del valor de un registro de una BD por que como la mia esta en Internet, es muy tardado, quisiera que fuera algo directo

ecfisa 31-07-2010 22:48:05

Hola flystar, Neftalí se refiere a hagas lo siguiente:

. Crees un campo calculado "tbPintar" por Ej. y pongas la propiedad del DBGrid: Options -> dgRowSelect igual a True.

. En el evento OnDblClick Pones a True tbPintar. (1)

. Pintas en el evento OnDrawColumnCell. (2)

(1)
Código:

procedure TForm1.DBGrid1DblClick(Sender: TObject);
begin
  tb.Edit;
  tbPintar.Value:= True;
end;

(2)
Código:

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
  if gdSelected in State then
    with DBGrid1 do
    begin
      if tbPintar.Value then  // color azul, fondo blanco
      begin
        Canvas.brush.Color:= clBlue;
        Canvas.Font.Color:= clWhite;
      end
      else                    // color por defecto del DBGrid
      begin
        Canvas.Brush.Color:= clWindow;
        Canvas.Font.Color:= clBlack;
      end;
      DefaultDrawColumnCell(Rect, DataCol, Column, State); // pintar
    end;
end;

Saludos.

flystar 02-08-2010 16:44:38

Muchas Gracias.
 
Muchas Gracias por la respuesta, es una excelente slución! :rolleyes::rolleyes::rolleyes::rolleyes:

roman 02-08-2010 17:38:32

¿Esto funciona? Lo he probado pero, si bien me permite colorear una fila, al desplazarme a otro registro se pierde el valor del campo calculado.

// Saludos

Neftali [Germán.Estévez] 02-08-2010 17:59:18

Cita:

Empezado por roman (Mensaje 372319)
¿Esto funciona? Lo he probado pero, si bien me permite colorear una fila, al desplazarme a otro registro se pierde el valor del campo calculado.

Bueno, yo creo que el campo debe estar físicamente en la tabla. No creo haber nombrado "campo calculado" en mi comentario y si lo he hecho he cometido un error.

roman 02-08-2010 18:20:44

Sí, lo sé. La pregunta era más bien para ecfisa, pues me extrañó que pudiera modificarse un campo calculado.

// Saludos

flystar 02-08-2010 18:57:56

Gracias
 
Lo mas adecuado es guardar el valor de la fila seleccionada en una variable global.

luego forzar un Refresh de la tabla y en el evento ondraw
comparar el valor de cierto campo que se esta dibujando con la variable y si es igual entonces se pinta.

Asi no hay tardanza!!!

Código:

filapintada:=ModuloDeDatos.QSeguimientoProspectacion.fieldbyname('idprospecto').asinteger;
 dxdbgrid1.FullRefresh;


Código:

  if modulodedatos.QSeguimientoProspectacion.fieldbyname('idprospecto').asinteger=filapintada then
  begin
        Acolor:=clyellow;
        Afont.Color:=Clblack
  end;


flystar 02-08-2010 19:00:52

Nota
 
Cabe señalara que obviamente los eventos y valores dependen del componente que usen como grid...
yo uso uno DXDBGRID (muy bueno)

El problema de usar campos de una BD es que si es por internet se pone lenta la seleccion y el pintado y el cliente o Jefe buscan rapidez..
a ellos no les importa lo que suframos para lograr sus peticiones.

jjeje

rgstuamigo 02-08-2010 22:03:22

Bueno ..creo con en éste hilo ya se te ha respondido y dado solucion, ya sea el uno u otro caso.;)
Saludos...:)

roman 02-08-2010 23:43:19

He estado viendo esto un rato y me parece que puede lograrse usando simplemente la propiedad SelectedRows del DBGrid pero poniendo en false la opción dgMultiSelect.

En el evento OnDblClick del DBGrid pondríamos:

Código Delphi [-]
procedure TForm1.DBGrid1DblClick(Sender: TObject);
begin
  DBGrid1.SelectedRows.CurrentRowSelected :=
    not DBGrid1.SelectedRows.CurrentRowSelected;
end;

y en el evento OnDrawColumnCell:

Código Delphi [-]
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
  if DBGrid1.SelectedRows.CurrentRowSelected then
  begin
    DBGrid1.Canvas.Brush.Color := clGreen;
    DBGrid1.Canvas.Font.Color := clHighlightText;
  end
  else
  begin
    DBGrid1.Canvas.Brush.Color := clWindow;
    DBGrid1.Canvas.Font.Color := clWindowText;
  end;

  DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;

// Saludos

ecfisa 03-08-2010 01:20:25

Hola a todos.

Cita:

Estoy buscando la manera de colorear una fila completa de un dbgrid, estuve buscando y no encontre nada.
El tema es el siguiente, tengo un dbgrid con una serie de informacion ahora cuando hago dbl click en una fila determinada que puede ser cualquiera ahi recien se tiene que colorear la misma, se puede hacer esto de alguna manera?
Si, el valor del campo calculado se pierde, tiene la función de una bandera.

Pero según expone flystar en el texto mencionado; sólo quiere que la fila seleccionada se coloree cuando haga doble click sobre ella.

En ningún momento entendí que quisiera utilizar el valor del campo extra para algún fin.
Y utilizando el campo calculado se evita "ensuciar" la tabla original.

De todos modos parece que era lo que andaba buscando... :)

Neftalí: No cometiste un error, fuí yo que hice una libre interpretación del texto... :)
Casimiro: Probé el ejemplo sin problemas asignando el valor al campo calculado.


Saludos.

ecfisa 03-08-2010 23:29:48

Hola.

Donde dice:
Cita:

Casimiro: Probé el ejemplo sin problemas asignando el valor al campo calculado.


Queria decir:

Roman:Probé el ejemplo sin problemas, asignando el valor al campo calculado.

Era tarde y andaba con la red neuronal en corto... :D

Román: Tu código también funciona, la diferencia es que deja seleccionadas las filas donde se hizo doble click, no digo con esto que esté mál. Ambos comportamientos pueden ser deseados.

Saludos y perdón por la confusión.

BlueSteel 10-02-2011 23:53:00

Hola

Estaba revisando esto, y necesito hacer algo parecido, solo debo pintarla, el otro problema es que el foco no lo tengo asignado al DBGrid...

Mi consulta es si le asigno el campo calculado al DBGrid (esto no lo he probado.. asi que ahora le meteré manos...)y sin asignación de focus, este me lo pintará....

Salu2...:p:cool:

se me olvidaba... para seleccionar la fila, lo hago en el Query que esta asignado al DBGrid, de la siguiente forma

Código Delphi [-]
Datos.AQ_IngresoGral.Locate('Tar_CodigoBarra',StrToInt(sFol.Text),[]);

ecfisa 11-02-2011 08:43:09

Hola BlueSteel.

Si te entendí bién, este código debería hacer lo que buscas. Lo asigné al evento OnClick de un TButton, pero vos podés ponerlo en el evento
que te convenga para el caso.
Hice en el DataSet un campo calculado que bauticé: Q_IngresoGralPintarGrid (en honor al DataSet:)) y usé el editor de columnas del DBGrid
para evitar visualizarlo. Un TEdit recibe el dato que se le pasará al Locate en el evento OnClick del TButton.

Código Delphi [-]
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
  if AQ_IngresoGralPintarGrid.Value then
  begin
    DBGrid1.Canvas.brush.Color:= clBlue;
    DBGrid1.Canvas.Font.Color:= clWhite;
  end
  else
  begin
    DBGrid1.Canvas.Brush.Color:= clWindow;
    DBGrid1.Canvas.Font.Color:= clBlack;
  end;
  DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State)
end;

Llamada:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
begin
  AQ_IngresoGral.Locate('NOMBRE', Edit1.Text, []);
  AQ_IngresoGral.Edit;
  AQ_IngresoGralPintarGrid.Value:= True;
end;

El código deja pintada la fila en que te ubicaste con Locate hasta que realices un nuevo posicionamiento, sin que haya necesidad de darle
el foco al TDBGrid.

Un saludo.

BlueSteel 11-02-2011 16:35:01

Excelente....

Era justo lo que estaba buscando.... te confieso que al principio no entendí mucho de donde crear el campo calculado, asi que me puse a instrusear... y es muy facil...

Y como tengo dos DBGrids en donde se muestran los datos de ingresos por la puerta actual y los ingresos que se realizan por todas las puertas, tube que realizar esto para que me pintará el dato de la puerta actual solo si ha ingresado por ahí

Código Delphi [-]
If Datos.AQ_Ingreso.Locate('Tar_CodigoBarra',StrToInt(sFol.Text),[]) Then
   Begin
           Datos.AQ_Ingreso.Edit;
           Datos.AQ_IngresoPintaGrid.Value:= True;
   End;

Gracias

Salu2:p:cool:


La franja horaria es GMT +2. Ahora son las 22:24:07.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi