Coloque un TCheckBox dentro de un TStringGrid en Delphi
checkbox grid delphi 7 (3)
Quiero poner un TCheckBox
dentro de un TStringGrid
en Delphi en cada celda de cierta columna. Estoy usando Delphi XE.
No intente colocar un control TCheckBox
real dentro de un TStringGrid
. Utilice el evento OnDrawCell
la cuadrícula con la función Win32 API DrawFrameControl()
lugar, para dibujar una imagen de un control CheckBox dentro de cada celda según sea necesario. Puede usar los eventos OnClick/OnMouse...
con la propiedad Objects[][]
la cuadrícula para realizar un seguimiento del estado comprobado de cada celda según sea necesario. Encuentro que esto es mucho más fácil de administrar, ya que TStringGrid
no fue diseñado para alojar controles reales.
Utilizo una cuadrícula virtual llamada ExGridView por Roman Mochalov, que admite casillas de verificación.
Mi propia bifurcación modificada de GridView, portada para Unicode, etc., llamada TExGridView, en lugar de TGridView, y con una demostración de casillas de verificación está en bitbucket aquí como / wpostma / exgridview.
El componente ExGridView tiene una propiedad de casilla de verificación en el inspector de propiedades que debe establecerse como verdadera. Luego, debe configurar las propiedades de columna para que la columna tenga un tipo de casilla de verificación establecido en casilla de verificación o botón de opción. Luego debe implementar la devolución de llamada del evento GetCheckState. Vea la demostración incluida en el proyecto bitbucket.
La fuente original para este código estaba aquí, pero no es editable en versiones recientes. Mi versión bitbucket está probada y funciona con Delphi 2007, 2009, y todas las versiones están actualizadas a partir de 2016 (Delphi 10 Seattle).
Debería dibujar sus propias casillas de verificación, preferiblemente utilizando temas visuales, si está habilitado. Este es un simple bosquejo de cómo hacer eso:
const
Checked: array[1..4] of boolean = (false, true, false, true);
procedure TForm4.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
const
PADDING = 4;
var
h: HTHEME;
s: TSize;
r: TRect;
begin
if (ACol = 2) and (ARow >= 1) then
begin
FillRect(StringGrid1.Canvas.Handle, Rect, GetStockObject(WHITE_BRUSH));
s.cx := GetSystemMetrics(SM_CXMENUCHECK);
s.cy := GetSystemMetrics(SM_CYMENUCHECK);
if UseThemes then
begin
h := OpenThemeData(StringGrid1.Handle, ''BUTTON'');
if h <> 0 then
try
GetThemePartSize(h,
StringGrid1.Canvas.Handle,
BP_CHECKBOX,
CBS_CHECKEDNORMAL,
nil,
TS_DRAW,
s);
r.Top := Rect.Top + (Rect.Bottom - Rect.Top - s.cy) div 2;
r.Bottom := r.Top + s.cy;
r.Left := Rect.Left + PADDING;
r.Right := r.Left + s.cx;
DrawThemeBackground(h,
StringGrid1.Canvas.Handle,
BP_CHECKBOX,
IfThen(Checked[ARow], CBS_CHECKEDNORMAL, CBS_UNCHECKEDNORMAL),
r,
nil);
finally
CloseThemeData(h);
end;
end
else
begin
r.Top := Rect.Top + (Rect.Bottom - Rect.Top - s.cy) div 2;
r.Bottom := r.Top + s.cy;
r.Left := Rect.Left + PADDING;
r.Right := r.Left + s.cx;
DrawFrameControl(StringGrid1.Canvas.Handle,
r,
DFC_BUTTON,
IfThen(Checked[ARow], DFCS_CHECKED, DFCS_BUTTONCHECK));
end;
r := Classes.Rect(r.Right + PADDING, Rect.Top, Rect.Right, Rect.Bottom);
DrawText(StringGrid1.Canvas.Handle,
StringGrid1.Cells[ACol, ARow],
length(StringGrid1.Cells[ACol, ARow]),
r,
DT_SINGLELINE or DT_VCENTER or DT_LEFT or DT_END_ELLIPSIS);
end;
end;
Por supuesto, en un escenario real, la matriz Checked
no es una constante, y es posible que desee guardar las métricas y el manejador de tema h
entre eventos de pintura de celda. Pero el principio está aquí.
http://privat.rejbrand.se/stringcheck1.png http://privat.rejbrand.se/stringcheck2.png
Lo que falta aquí es una función para alterar el estado de las casillas de verificación. Es probable que desee alternar el estado en un controlador OnClick
. Si habla en serio, también deseará responder al movimiento del mouse y mostrar el efecto de desplazamiento del mouse sobre las casillas de verificación si hay temas disponibles.
EDITAR por azulado: para alternar el estado de la casilla de verificación , esta respuesta explica cómo puede usar el método de Invalidate
.