Saltar al contenido

Ponga un TCheckBox dentro de un TStringGrid en Delphi

Recuerda que en las ciencias un error casi siempere suele tener diversas soluciones, de igual modo aquí mostramos lo mejor y más óptimo.

Solución:

Debe dibujar sus propias casillas de verificación, preferiblemente usando temas visuales, si está habilitado. Este es un esquema simple de cómo hacerlo:

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, el Checked array no es una constante, y es posible que desee guardar el s métricas y h identificador de tema entre eventos de pintura de celdas. Pero el principio está aquí.

Lo que falta aquí es una función para alterar el estado de las casillas de verificación. Probablemente querrá alternar el estado en un OnClick manipulador. Si es realmente serio, también deseará responder al movimiento del mouse y mostrar el efecto de desplazamiento del mouse en 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 puedes usar Invalidate método.

No trate de colocar un real TCheckBox controlar dentro de un TStringGrid. Usa la grilla OnDrawCell evento con la API de Win32 DrawFrameControl() en su lugar, para dibujar una imagen de un control CheckBox dentro de cada celda según sea necesario. Puedes usar el OnClick/OnMouse... eventos con la grilla Objects[][] propiedad para realizar un seguimiento del estado marcado de cada celda según sea necesario. Creo que esto es mucho más fácil de manejar, ya que TStringGrid no fue diseñado para albergar controles reales.

Uso una cuadrícula virtual llamada ExGridView de 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 Checkbox en el inspector de propiedades que debe configurarse trueLuego, debe configurar las propiedades de su 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 de este código estaba aquí, pero no se puede compilar en versiones recientes. Mi versión de bitbucket está probada y funciona con Delphi 2007, 2009 y todas las versiones actualizadas a partir de 2016 (Delphi 10 Seattle).

ingrese la descripción de la imagen aquí

Sección de Reseñas y Valoraciones

Si te apasiona la informática, tienes el poder dejar un tutorial acerca de qué te ha impresionado de este ensayo.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *