Поместите чекбокс внутри TStringGrid в Delphi

Я хочу поставить TCheckBox внутри TStringGrid в Delphi в каждой ячейке определенного столбца. Я использую Delphi XE.

3 ответов


вы должны нарисовать свои собственные флажки, предпочтительно используя визуальные темы, если они включены. Это простой набросок того, как это сделать:

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;

конечно, в реальном случае Checked массив не является константой, и вы можете сохранить s метрики и h тема ручка между событиями рисования ячеек. Но принцип здесь.

http://privat.rejbrand.se/stringcheck1.png http://privat.rejbrand.se/stringcheck2.png

здесь отсутствует функция для alter состояние чекбоксов. Вероятно, вы захотите переключить состояние в OnClick обработчик. Если вы действительно серьезны, вы также захотите ответить на движение мыши и отобразить эффект наведения мыши на флажки, если темы доступный.

редактировать bluish:для переключения состояния флажка, ответ объясняет, как вы можете использовать Invalidate метод.


Не пытайтесь разместить фактический TCheckBox контроль внутри TStringGrid. Используйте сетку OnDrawCell событие с Win32 API DrawFrameControl() функция вместо этого, чтобы нарисовать изображение элемента управления CheckBox внутри каждой ячейки по мере необходимости. Вы можете использовать OnClick/OnMouse... события с сеткой Objects[][] свойство для отслеживания состояния каждой ячейки при необходимости. Я считаю, что это намного проще в управлении, так как TStringGrid не предназначен для размещения реальных элементов управления.


Я использую виртуальную таблицу под названием ExGridView Роман Мочалов, который поддерживает флажки.

моя собственная измененная вилка GridView, портированная для Unicode etc, названная TExGridView, вместо TGridView, и с демонстрацией флажков находится на bitbucket здесь as/wpostma / exgridview.

компонент ExGridView имеет свойство Checkbox в инспекторе свойств, которое должно быть установлено true, затем необходимо настроить свойства столбца так, чтобы столбец имеет тип флажка, установленный на флажок или переключатель. Затем необходимо реализовать обратный вызов события GetCheckState. См. демонстрацию, включенную в проект bitbucket.

исходный код был здесь но он не строится на последних версиях. Моя версия bitbucket протестирована и работает с Delphi 2007, 2009 и всеми версиями до 2016 года (Delphi 10 Seattle).

enter image description here