Поместите чекбокс внутри 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).