delphi - CheckBox en una DBGrid
tcheckbox (4)
Disculpe por publicar esto como respuesta, aún no tengo la reputación de agregar comentarios.
La respuesta de Mihai MATEI es muy similar a la solución rara (como en realidad funciona), excepto por un caso de uso donde se produce un error.
Siempre que la primera acción de los usuarios en la cuadrícula sea hacer clic en la casilla de verificación, el primer clic funcionará, pero el segundo revelará el editor DBGrid subyacente.
Esto sucede porque el mecanismo "GridOriginalOptionsmechan" debe inicializarse. Para hacerlo, simplemente agregue el siguiente código en el evento OnEnter de la grilla:
procedure TForm1.DBGrid1Enter(Sender: TObject);
begin
DBGrid1ColEnter(Sender);
end;
¡Eso es!
Mi pregunta es cómo configurar una columna en dbgrid en Delphi 7, que estará con un elemento de casilla de verificación.
Gracias por adelantado.
El método más fácil y completo que probé es el siguiente:
En la sección privada de su unidad, declare un global para retener las opciones de la grilla. Se usará para restaurar después de la edición temporal de texto de desactivación al ingresar la columna de casilla de verificación, ya que este es quizás uno de los pequeños errores mencionados por Jordan Borisovin en relación con el artículo delphi.about.com
private
GridOriginalOptions : TDBGridOptions;
En el evento OnCellClick, si el campo es booleano, alternar y publicar cambios en la base de datos
procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
if (Column.Field.DataType=ftBoolean) then
begin
Column.Grid.DataSource.DataSet.Edit;
Column.Field.Value:= not Column.Field.AsBoolean;
Column.Grid.DataSource.DataSet.Post;
end;
end;
Dibujando la casilla de verificación para campos booleanos de la grilla
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
const
CtrlState: array[Boolean] of integer = (DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or DFCS_CHECKED) ;
begin
if (Column.Field.DataType=ftBoolean) then
begin
DBGrid1.Canvas.FillRect(Rect) ;
if (VarIsNull(Column.Field.Value)) then
DrawFrameControl(DBGrid1.Canvas.Handle,Rect, DFC_BUTTON, DFCS_BUTTONCHECK or DFCS_INACTIVE)
else
DrawFrameControl(DBGrid1.Canvas.Handle,Rect, DFC_BUTTON, CtrlState[Column.Field.AsBoolean]);
end;
end;
Ahora la parte nueva, deshabilita la edición de la celda mientras está en la columna booleana. En los eventos OnColEnter y OnColExit:
procedure TForm1.DBGrid1ColEnter(Sender: TObject);
begin
if Self.DBGrid1.SelectedField.DataType = ftBoolean then
begin
Self.GridOriginalOptions := Self.DBGrid1.Options;
Self.DBGrid1.Options := Self.DBGrid1.Options - [dgEditing];
end;
end;
procedure TForm1.DBGrid1ColExit(Sender: TObject);
begin
if Self.DBGrid1.SelectedField.DataType = ftBoolean then
Self.DBGrid1.Options := Self.GridOriginalOptions;
end;
Aún más, maneje la tecla de espacio para alternar la casilla de verificación
procedure TForm1.DBGrid1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if ((Self.DBGrid1.SelectedField.DataType = ftBoolean) and (key = VK_SPACE)) then
begin
Self.DBGrid1.DataSource.DataSet.Edit;
Self.DBGrid1.SelectedField.Value:= not Self.DBGrid1.SelectedField.AsBoolean;
Self.DBGrid1.DataSource.DataSet.Post;
end;
end;
¡Eso es!
OK, utilicé este artículo para mi problema. OK, pero el problema es que no funcionaba como debería. Entonces cambio mi lógica en el código. E implementarlo guardando las filas seleccionadas de dbgrid en una lista.
Si está utilizando TClientDataset + TDatasetProvider + TDataset, puede manipular la variante del conjunto de datos antes de que llegue al conjunto de datos del cliente e incluir un campo booleano no actualizable.
Una vez hecho, todo lo que necesita es dibujar en la cuadrícula utilizando el evento OnDrawColumnCell. Aquí no uso CheckBox sino solo un mapa de bits (cuando el usuario hace clic en él cambia a seleccionado / no seleccionado).