ale*_*zm1 10 delphi tstringgrid delphi-xe tcheckbox
我想提出一个TCheckBox内部TStringGrid在Delphi中某列的每一个细胞.我正在使用Delphi XE.
And*_*and 28
您应该绘制自己的复选框,最好使用视觉主题(如果已启用).这是如何做到这一点的简单草图:
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;
Run Code Online (Sandbox Code Playgroud)
当然,在实际场景中,Checked数组不是常量,您可能希望在单元格绘制事件之间保存s度量和h主题句柄.但原则就在这里.
http://privat.rejbrand.se/stringcheck1.png http://privat.rejbrand.se/stringcheck2.png
这里缺少的是一个改变复选框状态的功能.您可能希望在OnClick处理程序中切换状态.如果您真的很认真,那么您还希望响应鼠标的动作,并在主题可用时在复选框上显示鼠标悬停效果.
EDIT by bluish:要切换复选框状态,这个答案解释了如何使用Invalidate方法.
不要试图将实际TCheckBox控件置于其中TStringGrid.使用OnDrawCell带有Win32 API DrawFrameControl()函数的网格事件,根据需要在每个单元格内绘制CheckBox控件的图像.您可以使用OnClick/OnMouse...具有网格Objects[][]属性的事件来根据需要跟踪每个单元格的已检查状态.我发现这很容易管理,因为TStringGrid它不是为了托管真正的控件而设计的.