Я хочу поставить TCheckBox
внутри TStringGrid
в Delphi в каждой ячейке определенного столбца. Я использую Delphi XE.
Поместите TCheckBox внутри TStringGrid в Delphi
Ответ 1
Вы должны нарисовать свои собственные флажки, желательно с использованием визуальных тем, если они включены. Это простой набросок того, как это сделать:
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
между событиями рисования ячеек. Но принцип здесь.
Здесь не хватает функции для изменения состояния флажков. Возможно, вы захотите переключить состояние в обработчике OnClick
. Если вы действительно серьезны, вам также следует реагировать на движение мыши и отображать эффект наведения мыши на флажки, если доступны темы.
РЕДАКТИРОВАНИЕ синим цветом: Чтобы переключить состояние флажка, этот ответ объясняет, как можно использовать метод Invalidate
.
Ответ 2
Не пытайтесь установить фактический элемент управления TCheckBox
внутри TStringGrid
. Используйте событие grid OnDrawCell
с помощью функции Win32 API DrawFrameControl()
, чтобы нарисовать изображение элемента управления CheckBox внутри каждой ячейки по мере необходимости. Вы можете использовать события OnClick/OnMouse...
с помощью свойства grid Objects[][]
, чтобы отслеживать состояние каждой ячейки, если необходимо. Я считаю, что это намного проще в управлении, поскольку TStringGrid
не предназначен для размещения реальных элементов управления.
Ответ 3
Я использую виртуальную сетку под названием ExGridView Романа Мочалова, который поддерживает флажки.
Мой собственный модифицированный виль GridView, портированный для Unicode и т.д., с именем TExGridView вместо TGridView и с демонстрацией флажков находится на битбакете здесь as/wpostma/exgridview.
Компонент ExGridView имеет свойство Checkbox в инспекторе свойств, которое должно быть установлено true. Затем вы должны настроить свои свойства столбца, чтобы в столбце был установлен флажок, установленный на флажок или переключатель. Затем вы должны реализовать обратный вызов события GetCheckState. См. Демонстрацию, включенную в проект bitbucket.
Исходный источник этого кода был здесь, но он не может быть создан для последних версий. Моя версия bitbucket протестирована и работает с Delphi 2007, 2009 и всеми версиями до 2016 года (Delphi 10 Seattle).
Ответ 4
перейдите на эту страницу http://www.sql.ru/forum/189447/checkbox-v-stringgrid см. простой пример Delphi на этой странице