Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   CheckBox en un Grid (https://www.clubdelphi.com/foros/showthread.php?t=12672)

JorgeBec 23-07-2004 16:04:46

CheckBox en un Grid
 
Hola Comunidad! De casualidad alguien sabe como poner un CheckBox en un Grid???, obviamente el campo que relacione al Grid es un campo logico...


agradecere sus respuestas...

Neftali [Germán.Estévez] 23-07-2004 16:49:18

Cita:

Empezado por JorgeBec
...alguien sabe como poner un CheckBox en un Grid???

http://delphi.about.com/library/weekly/aa082003a.htm

Explicadito paso a paso con sus dibujos y todo...;)

Un saludo

Ita 23-07-2004 21:00:36

Jedi VCL for Delphi
 
Si mal no recuerdo, existe un componente dentro de los Jedi VCL for Delphi que hace exactamente eso que tu necesitas sin mayor esfuerzo. Estos componentes estan disponibles para delphi 5,6,7 (hasta donde estaba enterada).

Si te interesan bájatelos de la siguiente dirección:
http://sourceforge.net/project/showf...group_id=45786

ContraVeneno 18-07-2005 23:13:38

Ita, Ya instale la JVCL 3.0 pero son tantos componentes que estoy un poco perdido. ¿sabes como se llama ese componentes dentro de las JVCL?

Lepe 19-07-2005 17:12:40

Si lo encuentras avisa, porque yo lo he buscado y no lo he encontrado :D

Un saludo

Lepe 19-07-2005 17:15:55

Aunque la verdad, no creo que haya que complicarse tanto la vida por tan poca cosa:
Código Delphi [-]
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; 
  DataCol: Integer; Column: TColumn; State: TGridDrawState); 
var 
  Check: Integer; 
  R: TRect; 
begin 
  if Column.FieldName = 'NombreCampo' then 
  begin 
    DBGrid1.Canvas.FillRect(Rect); 
    Check := 0; 
    if Table1.FindField('NombreCampo').AsInteger = 1 then Check := DFCS_CHECKED; 
    R:=Rect; 
    InflateRect(R,-2,-2); //Disminuye el tamaño del CheckBox 
    DrawFrameControl(DBGrid1.Canvas.Handle,R,DFC_BUTTON, DFCS_BUTTONCHECK or Check); 
  end; 
end; 


procedure TForm1.DBGrid1CellClick(Column: TColumn); 
begin 
  if Column.FieldName = 'NombreCampo' then 
  begin 
    Table1.Edit; 
    if Table1.FindField('NombreCampo').AsInteger = 1 then
    Table1.FindField('NombreCampo').AsInteger := 0
    else
    Table1.FindField('NombreCampo').AsInteger := 1
    Table1.Post;
    Dbgrid1.Refresh; // quizás más bien un Repaint.... pero en fin.
  end; 
end;

el_barto 19-07-2005 17:36:41

ahhhh MALDICION GITANA no me dibuja el check en ningun lado

ContraVeneno 19-07-2005 17:48:10

Pues con el ejemplo que menciona neftali de Delphi.About a mi si me lo dibuja bien.

el_barto 19-07-2005 18:13:46

y que le modificaste aqui para con datos integer:


Código Delphi [-]
if (Column.Field.FieldName = DBCheckBox1.DataField) then
    begin
     DBCheckBox1.Left := Rect.Left + DBGrid1.Left + 2;
     DBCheckBox1.Top := Rect.Top + DBGrid1.top + 2;
     DBCheckBox1.Width := Rect.Right - Rect.Left;
     DBCheckBox1.Height := Rect.Bottom - Rect.Top;

     DBCheckBox1.Visible := True;
    end

por que a este if no entra nunca dado que el checkbox nunca me lo pone visible

ContraVeneno 19-07-2005 18:50:57

La columna del Grid y el DBCheckBox deben tener definido el mismo campo.
En el DBCheckBox hay que definirle las propiedades ValueChecked y ValueUnChecked a los valores que vas a tomar como cierto y falso.
Ejemplo: ValueChecked=1 para verdadero y ValueUnChecked=0 para falso.

el_barto 19-07-2005 19:18:05

Sisisi pero no ves que asi me saca un error que dice:

cannot acces field 'prodcre' as type boolean

donde prodcre es mi campo integer

el_barto 19-07-2005 20:48:01

si ves entonces por eso te pregunto que hay que modificar para que acepte el valor no boolean sino integer.

Ayudame please

ContraVeneno 19-07-2005 20:52:20

Si, bueno, hasta ahora todas los grids que he visto que ponen un checkbox son para campos tipo boolean.

Lepe: la dbGrid del JVCL pone el checkbox de manera automática si el campo esta definido como boolean (bit para SQL Server)

Dos opciones:
1.- Seguir buscando y jugar con el código para que tome un valor entero como boolean.

(editado)....... despues de leer el post de maeyanes esto no tiene mcuho sentido....

2.- Que definas otro campo tipo boolean en tu base de datos.

Supongo que lo más sencillo sería la segunda opción, de cualquie rmanera dejame ver que más se me ocurrre.

maeyanes 19-07-2005 21:16:37

El problema es que su versión de Interbase es menor a la 7, y esta no ofrece soporte a campos booleanos.

el_barto 19-07-2005 21:22:45

la segunda no por que uso interbase y no permite crear datos boolean

mira yo tengo este codigo pero tiene dos problemas imprime checkbox fuera de la grilla y no se pueden modificar como en esta.

es decir si el checkbox esta checked no lo puedes pasar a unchecked:


Código Delphi [-]
procedure TForm1.DrawColumnCell(const Rect: TRect; DataCol: Integer;
  Column: TColumn; State: TGridDrawState);
const
  CtrlState: array[Boolean] of Integer = (DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or DFCS_CHECKED);
var
  Exit: boolean;
  IsTrue: boolean;
  CheckBoxRec: TRect;
begin
  // Control del pintado del CheckBox
  Exit := false;

  if not Assigned(Column) or not Assigned(Column.Field) then
    Exit := true;

  // sólo controlamos los campos booleanos o enteros 
  if not Exit and not (Column.Field.DataType in [ftBoolean, ftInteger, ftSmallint]) then
    Exit := true;

  // si el campo es entero, la propiedad Tag de la columna tiene que tener un 1 para imprimir el check
  if ((Column.Field.DataType = ftInteger) or (Column.Field.DataType = ftSmallint)) and
      (Column.Field.Tag = 1) then
    Exit := true;

  // miramos que valor (true/false) hay que asignar al CheckBox
  IsTrue := false;
  if Column.Field.DataType = ftBoolean then
    IsTrue := Column.Field.AsBoolean;
  if ((Column.Field.DataType = ftInteger) or (Column.Field.DataType = ftSmallint)) then
    IsTrue := Column.Field.AsInteger = 1;

  if not Exit then
  begin
    Self.Canvas.FillRect(Rect);
    CheckBoxRec.Left   := Rect.Left + 2;
    CheckBoxRec.Right  := Rect.Right - 2;
    CheckBoxRec.Top    := Rect.Top + 2;
    CheckBoxRec.Bottom := Rect.Bottom - 2;
    DrawFrameControl(Self.Canvas.Handle, CheckBoxRec, DFC_BUTTON, CtrlState[IsTrue]);
  end;
end;

pero el principal problema es que no me imprime el checkbox en la grilla pruebalo y veras

ContraVeneno 19-07-2005 22:48:29

vamos a ver...
aquí dibujo el checkbox en el grid, dame tiempo para probar si puedo hacer un edit y un post, pero por lo pronto aquí la primera parte. 0=falso, cualquier otra cosa =verdadero.

Código Delphi [-]
procedure TFrmInicial.DBGrid1DrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
var
  DrawState: Integer;
  DrawRect: TRect;
begin
  if (gdFocused in State) then
  begin
    if (Column.Field.FieldName = 'Campo') then
    begin
     CheckBox1.Left := Rect.Left + DBGrid1.Left + 2;
     CheckBox1.Top := Rect.Top + DBGrid1.top + 2;
     CheckBox1.Width := Rect.Right - Rect.Left;
     CheckBox1.Height := Rect.Bottom - Rect.Top;
     CheckBox1.Visible := True;
    end
  end
  else
  begin
    if (Column.Field.FieldName = 'Campo') then
    begin
      DrawRect:=Rect;
      InflateRect(DrawRect,-1,-1);
      if column.field.asinteger=0 then
       DrawState := DFCS_BUTTONCHECK
      else
       DrawState:= DFCS_CHECKED; 
      DBGrid1.Canvas.FillRect(Rect);
      DrawFrameControl(DBGrid1.Canvas.Handle, DrawRect,
                       DFC_BUTTON, DrawState);
    end;
  end; 
end;

el_barto 19-07-2005 23:19:50

checkbox en dbgrid campo NO BOOLEAN
 
Gracias por tu dedicacion eres un excelente forista n-mil gracias pero mira el codigo que use:

uso esto para dibujarlo:

Código Delphi [-]
 
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
Check: Integer;
begin
{ Compruebo antes si la tabla está vacía. }
if not IBTable1.IsEmpty then
begin
{ Campo 1. }
  if CompareText(Column.FieldName, 'cod_per') = 0 then
  begin
    Check := 0;
  if IBTable1['cod_per'] = '1' then
   Check := DFCS_CHECKED;
   dbGrid1.Canvas.FillRect(Rect);
   DrawFrameControl(dbGrid1.Canvas.Handle, Rect,
   DFC_BUTTON, DFCS_BUTTONCHECK or Check);
  end
else
dbgrid1.DefaultDrawColumnCell(Rect,DataCol,Column,State);

{ Campo 2. }
if CompareText(Column.FieldName, 'user_name') = 0 then
begin
Check := 0;
  if IBTable1['user_name'] = '1' then
   Check := DFCS_CHECKED;
   dbGrid1.Canvas.FillRect(Rect);
   DrawFrameControl(dbGrid1.Canvas.Handle, Rect,
   DFC_BUTTON, DFCS_BUTTONCHECK or Check);
  end
else
dbgrid1.DefaultDrawColumnCell(Rect,DataCol,Column,State);

{ Campo 3. }
if CompareText(Column.FieldName, 'prodcre') = 0 then
  begin
  Check := 0;
   if IBTable1['prodcre'] = '1' then
      Check := DFCS_CHECKED;
      dbGrid1.Canvas.FillRect(Rect);
      DrawFrameControl(dbGrid1.Canvas.Handle, Rect,
     DFC_BUTTON, DFCS_BUTTONCHECK or Check);
   end
else
   dbgrid1.DefaultDrawColumnCell(Rect,DataCol,Column,State);
end;
end;

y esto para cambiarlo cuando se haga un click en el campo deseado:

Código Delphi [-]
 
procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
  if Column.FieldName = 'PRODCRE' then
   begin
     IBTable1.Edit;
     if IBTable1.FindField('PRODCRE').AsInteger = 1 then
       IBTable1.FindField('PRODCRE').AsInteger := 0
     else
       IBTable1.FindField('PRODCRE').AsInteger := 1;
       IBTable1.Post;
       Dbgrid1.Repaint; // quizás más bien un Repaint.... pero en fin.
     end;
end;

Y pues le agregaria un boton que hiciera un commit.

Si te das cuenta es una combinacion de algunas de las respuestas publicadas en este foro

Entonces cuando alguien necesite un checkbox dentro de un dbgrid y el campo no sea booleano ya lo puede hacer asi. probado comprobado y recontraprobado :D :D :D

ContraVeneno 19-07-2005 23:23:21

Perfecto :D :D
Ya estaba pensando cosas de más y tratando de inventar el hilo negro :D :D
En fin, que bueno que ya lo resolviste, un saludo!

el_barto 19-07-2005 23:30:47

El hilo maldito, el hilo malo mas malo que matar a la mama a pelliscos

Lepe 20-07-2005 10:11:05

Cita:

Empezado por el_barto
y que le modificaste aqui para con datos integer:


Código Delphi [-]
if (Column.Field.FieldName = DBCheckBox1.DataField) then
    begin
     DBCheckBox1.Left := Rect.Left + DBGrid1.Left + 2;
     DBCheckBox1.Top := Rect.Top + DBGrid1.top + 2;
     DBCheckBox1.Width := Rect.Right - Rect.Left;
     DBCheckBox1.Height := Rect.Bottom - Rect.Top;

     DBCheckBox1.Visible := True;
    end

por que a este if no entra nunca dado que el checkbox nunca me lo pone visible

Ya llego tarde porque lo resolviste de otra forma; solo comentar que en ese if
no entra nunca porque no es DBCheckBox1.DataField sino
DBCheckBox1.FieldName
.

ContraVeneno, gracias por la info del checkbox en la JVCL. En realidad
yo necesitaba el checkbox sin asociarlo a un campo, pero es bueno saber que
lo tiene para campos boolean.

el barto, gracias por corroborar que solo hace falta un Repaint en el
grid para actualizar el campo. Si los datos vienen de un query, muy
posiblemente haya que cerrarlo y abrirlo de nuevo para que tome los datos de
nuevo.

Un saludo a todos


La franja horaria es GMT +2. Ahora son las 11:54:55.

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