PDA

Ver la Versión Completa : Cambiar color en panel de DBCtrlGrid segun valor de un atributo


akinom38
21-01-2006, 22:28:08
Hola buenas noches!

Estoy programando una aplicación para un restaurante utilizando Delphi6 y Paradox. Mi problema es el siguiente: Estoy utilizando un DBCtrlGrid para visualizar en un formulario todas las mesas de la tabla mesas. Dentro del DBCTrlGrid he dibujado un panel para dar la impresión de que sea un botón....y dentro de este panel tengo un DBText en el que muestro el nombre 'descripción' de la mesa. Además, la tabla mesas tiene un atributo llamado estado en el que guardo si la mesa está libre u ocupada. Si está libre quiero que el panel aparezca en verde y si no en rojo.
Bien, entonces en el evento onPaintPanel he implementado el siguiente código:

if (DBCtrlGrid1.DataSource.DataSet.FieldByName ('estado').AsString)='Libre' then
Panel1.Color :=clGreen
else
Panel1.Color :=clRed;
end;


Entonces, en principio, pues las pinta de ese color, pero en cuanto pasa el foco (o en el primer click) a una de las mesas de las que se suponen están en rojo, se ponen en verde por un momento y no sé como arreglarlo. Lo peor es si la primer mesa está en rojo, como en principio tiene el foco, pues aparece en verde.

Alquien tiene alguna idea de como solucionarlo? O si es posible hacer algo, u debería utilizar otro componente? No sé, cualquier idea es bien recibida...

Un saludo,

jmariano
21-01-2006, 23:35:39
Mas que usar el evento OnPaintPanel que sólo se ejecuta cuando el
DBCtrlGrid necesita ser "repintado", probaría a utilizar el evento del DataSource: OnDataChange (que se ejecuta cada vez que cambian los datos, ya sea por que se produjo un desplazamiento, etc.), de esta manera te asegurarías siempre de que los paneles se mostrarán en el color correcto.

Por ejemplo, si tienes el componente DataSource en el mismo formulario:

procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField);
begin
if (DataSource1.DataSet.FieldByName('estado').AsString) = 'Libre' then
Panel1.Color :=clGreen
else Panel1.Color :=clRed;
end;


(En caso de que lo tengas en un módulo de datos podrías crearte en el módulo una propiedad pública de tipo "evento", TNotifyEvent, que se ejecutara cada vez que cambiaran los datos, y capturar, luego, esta propiedad en el formulario)


Otra solución, tal vez más simple, sería probar a invocar al método Repaint del DBCtrlGrid cada vez que el panel recibe el foco (evento OnEnter) y ver si funciona. (Repaint obliga al DBCtrlGrid a "repintarse", así que, en teoría, tendría que funcionar).

Saludos!

akinom38
22-01-2006, 04:28:30
Hola, muy buenas. Antes de nada, muchas gracias por la respuesta.
Primeramente he probado con la última sugerencia de invocar al método Repaint en el evento OnEnter del Panel, pero no funciona.

Seguidamente he probado a usar el método OnDataChange del DataSource, quitando el código de OnPaintPanel, pero misteriosamente...hace cosas muy raras.

Finalmente, dejando el código que tenía OnPaintPanel y además añadiendolo también en OnDataChange, funciona bien para todos los casos menos para el primer registro. (Que debería de salir rojo, pero se pinta en verde hasta que clickeo en él). Antes de este cambio, además de ésto en las demás mesas rojas, al clickear por primera vez en ellas se pintaban en verde. Cosa que al añadir el código de OnDataChange ya no.

No sé si me he explicado bien o no....

Alguna sugerencia?

akinom38
22-01-2006, 19:09:57
Hola, bueno, creo que me voy a volver loca!!

A ver, ahora he probado sólo con el siguiente código en el evento OnPaintPanel del DBCtrlGrid:


begin
if (DBCtrlGrid1.DataSource.DataSet.FieldByName('estado').AsString)='Libre' then
DBCtrlGrid1.Color:=clGreen
else
DBCtrlGrid1.Color :=clRed;
end;


En vez de colorear el Panel, como antes, coloreo el DBCtrlGrid. Y cual es el resultado? Pues que si tienen que aparecer las mesas 1,2,3 y 15 en rojo. Aparecen en rojo las mesas 2,3,4 y 16. Alguna idea de por qué pasa ésto?

Un saludo,

akinom38
23-01-2006, 14:25:30
Hola a todos! Tras un paseillo por foros y otros lugares de Internet, lo que he conseguido es lo siguiente:

He quitado el Panel de antes, y el DBText lo pongo directamente.
Entonces con poner el siguiente código en el evento OnPaintPanel, funciona correctamente. (En vez de cambiar el color del panel, cambiamos el color del canvas, y luego lo dibujamos, ' o eso es lo que entiendo, vamos').


procedure TFSituacionMesas.DBCtrlGrid1PaintPanel(DBCtrlGrid: TDBCtrlGrid;
Index: Integer);
var
r: TRect;
begin
r := Rect(0,0,DBCtrlGrid1.PanelWidth-3,DBCtrlGrid1.PanelHeight-3);

// determinamos el color del panel
if DBCtrlGrid1.DataSource.DataSet.FieldByName('estado').AsString = 'Libre' then
DBCtrlGrid1.Canvas.Brush.Color := clGreen
else
DBCtrlGrid1.Canvas.Brush.Color := clRed;

// rellenar panel
DBCtrlGrid1.Canvas.FillRect(r);

// Dibujar el rectangulo del foco
if DBCtrlGrid1.PanelIndex = Index then
DBCtrlGrid1.Canvas.DrawFocusRect(r);
end;


Lo dejo, aquí por si a alguien le sirve de algo.
Aúnque lo haya solucionado de esta forma, si a alguien se le ocurre como arreglar el problema que tenía antes, o por qué pasaba eso, pues que lo comente. Más que nada, porque me he quedado con curiosidad....

Saludos,