我有一个网格组件(DBGrid),上面有很多列。由于大量的列,创建了一个滚动条,因此网格的某些部分仍然隐藏。我需要找出 DBGrid 的实际宽度是多少,包括由于滚动条而未显示的部分。但是 Width 属性只给出了组件本身的宽度。有人有什么想法吗?
问问题
3653 次
4 回答
2
TDBGrid
有财产Columns
。每个列都有自己的Width
属性。因此,您可以遍历所有列并总结它们的宽度。
像这样:
function TotalColumnsWidth(var AGrid: TDBGrid);
var
i: Integer;
begin
Result := 0;
for i := to AGrid.Columns.Count - 1 do
Result := Result + AGrid.Columns[i].Width;
end;
于 2009-11-11T17:50:26.507 回答
1
也许这可能会有所帮助。它是自动调整最后一列大小的 TDBGrid 类助手的一部分,因此网格没有空白空间。应该很容易适应您的需求。
您可能会注意到,CalcDrawInfo 方法正是您所寻求的。由于它受到保护,您可以使用类助手或通常的受保护黑客来获取它。
procedure TDbGridHelper.AutoSizeLastColumn;
var
DrawInfo: TGridDrawInfo;
ColNo: Integer;
begin
ColNo := ColCount - 1;
CalcDrawInfo(DrawInfo);
if (DrawInfo.Horz.LastFullVisibleCell < ColNo - 1) then Exit;
if (DrawInfo.Horz.LastFullVisibleCell < ColNo) then
ColWidths[ColNo] := DrawInfo.Horz.GridBoundary - DrawInfo.Horz.FullVisBoundary
else
ColWidths[ColNo] := ColWidths[ColNo] + DrawInfo.Horz.GridExtent - DrawInfo.Horz.FullVisBoundary
end;
于 2009-11-11T21:29:13.613 回答
0
我想我已经找到了解决方案(虽然看起来有点奇怪)。为了找到DBgrid的列宽和实际宽度之间的差异(即找到最后一列之后剩余的空白区域的宽度),我们需要跟踪现在左侧显示的是哪一列(当前列是什么滚动到)。我们可以使用 OnDrawColumnCell 事件来做到这一点,因为它只会绘制现在滚动的列。然后我们需要计算所有可见列的宽度之和,然后从 DBGrid 的宽度中减去它。PS对不起英语不好
防爆代码:
For i:=0 to Last do
if Vis[i] then
Begin
Sum:=Sum+DBG.Columns[i].Width;
Inc(Cnt);
End;
if dgColLines in DBG.Options then
Sum := Sum + Cnt;
//add indicator column width
if dgIndicator in DBG.Options then
Sum := Sum + IndicatorWidth;
Dif:=DBG.ClientWidth - Sum;
于 2009-11-11T19:02:16.840 回答
0
以下是我们过去使用过的功能。它会根据字体考虑数据的宽度,如果垂直线可见,也会对其进行补偿
function GridTextWidth(fntFont : TFont; const sString : OpenString) :
integer;
var
f: TForm;
begin
try
f:=TForm.Create(nil);
f.Font:=fntFont;
result:=f.canvas.textwidth(sstring);
finally
f.Free;
end;
end;
function CalcGridWidth(dbg : TDBGrid { the grid to meaure }): integer; { the "exact" width }
const cMEASURE_CHAR = '0';
iEXTRA_COL_PIX = 4;
iINDICATOR_WIDE = 11;
var i, iColumns, iColWidth, iTitleWidth, iCharWidth : integer;
begin
iColumns := 0;
result := GetSystemMetrics(SM_CXVSCROLL);
iCharWidth := GridTextWidth(dbg.font,cMeasure_char);
with dbg.dataSource.dataSet do begin
DisableControls;
for i := 0 to FieldCount - 1 do with Fields[i] do
if visible then
begin
iColWidth := iCharWidth * DisplayWidth;
if dgTitles in dbg.Options then begin
ititlewidth:=GridTextWidth(dbg.titlefont,displaylabel);
if iColWidth < iTitleWidth then
iColWidth := iTitleWidth;
end;
inc(iColumns, 1);
inc(result, iColWidth + iEXTRA_COL_PIX);
end;
EnableControls;
end;
if dgIndicator in dbg.Options then
begin
inc(iColumns, 1);
inc(result, iINDICATOR_WIDE);
end;
if dgColLines in dbg.Options then
inc(result, iColumns)
else
inc(result, 1);
end;
于 2009-11-11T19:25:44.050 回答