我正在尝试使用DBGrid
创建一个框架,该框架将用于超过10个表,其中一半字段为默认值,其他字段为每个表独占。
由于列的空间有限,我不想手动配置每个表的每一列,因为它是非常差的质量工作,我想知道一种方法来计算每列的最大内容的宽度该列内的行,由自己的组件或数据集测量。
有谁知道的方式?世界上有一些具有这种力量的定制组件吗? 根据网格所有可见列中的可见数据,我需要一个实现大小增加和减少的解决方案。 到目前为止,我的解决方案在绘制所选单元格时出现问题,从所选数据集行跳出。
注意:请不要关闭我的问题。它与网格的宽度或形状的宽度无关。它是关于所有列宽度以最小化水平滚动条,但不一定隐藏它。
答案 0 :(得分:10)
您需要做的是使用网格画布来测量每列的内容并相应地设置列的宽度。您可以遍历数据集或使用OnColumnDraw-Event来动态调整宽度。
这是一个示例(我必须使用5像素的偏移量)
procedure TForm7.DBGridDrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
Var
w : Integer;
begin
w := 5+DBGrid.Canvas.TextExtent(Column.Field.DisplayText).cx;
if w>column.Width then Column.Width := w;
end;
procedure TForm7.FormActivate(Sender: TObject);
Var
i : Integer;
begin
// Initialize width
for I := 0 to DBGrid.Columns.Count - 1 do
DBGrid.Columns[i].Width := 5 + DBGrid.Canvas.TextWidth(DBGrid.Columns[i].title.caption)
end;
答案 1 :(得分:7)
<强>编辑:强>
我的第一个代码是关于拟合网格中的列,使用这个新代码,AutoSizeColumns读取记录以计算每列的宽度,直到MaxRows或Dataset.Eof:
class function TDBGridHelper.AutoSizeColumns(DBGrid: TDBGrid; const MaxRows: Integer = 25): Integer;
var
DataSet: TDataSet;
Bookmark: TBookmark;
Count, I: Integer;
ColumnsWidth: array of Integer;
begin
SetLength(ColumnsWidth, DBGrid.Columns.Count);
for I := 0 to DBGrid.Columns.Count - 1 do
if DBGrid.Columns[I].Visible then
ColumnsWidth[I] := DBGrid.Canvas.TextWidth(DBGrid.Columns[I].Title.Caption + ' ')
else
ColumnsWidth[I] := 0;
if DBGrid.DataSource <> nil then
DataSet := DBGrid.DataSource.DataSet
else
DataSet := nil;
if (DataSet <> nil) and DataSet.Active then
begin
Bookmark := DataSet.GetBookmark;
DataSet.DisableControls;
try
Count := 0;
DataSet.First;
while not DataSet.Eof and (Count < MaxRows) do
begin
for I := 0 to DBGrid.Columns.Count - 1 do
if DBGrid.Columns[I].Visible then
ColumnsWidth[I] := Max(ColumnsWidth[I], DBGrid.Canvas.TextWidth(
DBGrid.Columns[I].Field.Text));
Inc(Count);
DataSet.Next;
end;
finally
DataSet.GotoBookmark(Bookmark);
DataSet.FreeBookmark(Bookmark);
DataSet.EnableControls;
end;
end;
Count := 0;
for I := 0 to DBGrid.Columns.Count - 1 do
if DBGrid.Columns[I].Visible then
begin
DBGrid.Columns[I].Width := ColumnsWidth[I];
Inc(Count, ColumnsWidth[I]);
end;
Result := Count - DBGrid.ClientWidth;
end;
我在DataSet.AfterOpen事件中调用它:
TGridHelper.AutoSizeColumns(MyDBGrid);
答案 2 :(得分:1)
为什么要使用如此复杂的代码? :D只需使用它。它也有5 px偏移量。
procedure TForm1.FormActivate(Sender: TObject);
var
i:integer;
begin
for i :=0 to DbGrid1.Columns.Count - 1 do
DbGrid1.Columns[i].width :=5+dbgrid1.Canvas.TextWidth(DbGrid1.Columns[i].Title.Caption);
end;
答案 3 :(得分:1)
对于您希望自动调整大小的每列,设置属性SizePriority=1
,对于固定列设置SizePriority=0
,在您的情况下,只有最后一列会自动调整大小。
然后设置属性grid.AutoFillColumns=true
,那应该这样做。
答案 4 :(得分:1)
对于TRUEDBGRID .net,您可以执行以下操作:
Private Sub AutoSizeGrid(Grid As C1.Win.C1TrueDBGrid.C1TrueDBGrid)
For Each Sp As C1.Win.C1TrueDBGrid.Split In Grid.Splits
For Each Cl As C1.Win.C1TrueDBGrid.C1DisplayColumn In Sp.DisplayColumns
Cl.AutoSize()
Next
Next
End Sub
对于vb60中的TrueDbGrid ActiveX,此代码(此代码不包含拆分):
Public Function APEXGridAutoFix(Grid As TrueOleDBGrid80.TDBGrid)
Dim Col As TrueOleDBGrid80.Column
For Each Col In Grid.Columns
Col.AutoSize
Next
End Function
答案 5 :(得分:0)
此解决方案使所有列根据其内容进行扩展或缩小,如果必须存在滚动条,则无需小心,并修复选定的单元格绘制故障和记录指针故障。
type
TColumnAutoAdjust = record {Save the information responsible for setting column widths in the grid}
Field: String; {Field name whose information is being stored}
Registered: Boolean; {Indicates whether the size of this column already registered}
Updated: Boolean; {Indicates the actual size of the column was updated}
LastWidth: Integer; {Width indicates the final text of a record of a row column}
CurrWidth: Integer; {Indicates the current size and column width}
Reverter: Integer; {Indicates the greatest width recorded but that is less than the current}
Scrolls: Integer; {Indicates the amount of scrolls present after one width adjustment}
RecNo: Integer; {Indicates which was the record in the table which increased the width of colune}
end;
var { inside the forms private }
gdCols: array of TColumnAutoAdjust; { vetor de ajuste de largura de cada coluna na grade de resultado }
RegisteredCols: Integer; { quantas colunas já foram registradas no controle de ajuste }
gdVisibleRows: Integer; { quantas linhas de cadastros estão visíveis da grade de resultado }
gdVisibleCols: Integer; { quantas colunas de cadastros estão visíveis da grade de resultado }
{ before showing the grid }
RegisteredCols := ResultGrid.Columns.Count;
SetLength(gdCols, RegisteredCols); { determina o tamanho da vetor de controle de colunas }
{ libera a lista }
ResultGrid.Align := alClient;
for i := 0 to RegisteredCols -1 do { inicializando a largura das colunas no tamanho do título de cada }
begin
gdCols[i].Field := ResultGrid.Columns[i].FieldName;
ResultGrid.Columns[i].Width := ResultGrid.Canvas.TextExtent(ResultGrid.Columns[i].Title.Caption).cx;
ResultGrid.Columns[i].Alignment := taLeftJustify;
ResultGrid.Columns[i].Title.Alignment := taLeftJustify;
end;
BrowserQuery.Open;
ResultGrid.Show;
for i := 0 to gdVisibleRows do
begin
BrowserQuery.Next;
ResultGrid.Refresh;
end;
for i := 0 to gdVisibleRows do
begin
BrowserQuery.Prior;
ResultGrid.Refresh;
end;
BrowserQuery.First;
ResultGrid.SetFocus;
end
{ after dataset scroll}
procedure TRecordsBrowserFrameBase.BrowserQueryAfterScroll(DataSet: TDataSet);
var
i, TitleWidth: Integer;
mayAdjustAgain: Boolean; { }
begin
{ ajusta as colunas da grade de resultado a cada movimento da tabela de resultado }
mayAdjustAgain := False;
for i := 0 to RegisteredCols -1 do
begin
if not gdCols[i].Updated then
begin
ResultGrid.Columns[i].Width := gdCols[i].CurrWidth;
gdCols[i].Scrolls := 0;
gdCols[i].Updated := True;
end
else
begin
Inc(gdCols[i].Scrolls);
if (DataSet.RecNo > gdCols[i].RecNo + gdVisibleRows) or (DataSet.RecNo < gdCols[i].RecNo - gdVisibleRows) then
begin
TitleWidth := MaxColSpacing + ResultGrid.Canvas.TextExtent(ResultGrid.Columns[i].Title.Caption).cx;
gdCols[i].LastWidth := gdCols[i].CurrWidth;
gdCols[i].CurrWidth := IFX(gdCols[i].Reverter > TitleWidth, gdCols[i].Reverter, TitleWidth);
gdCols[i].Reverter := IFX(gdCols[i].Reverter > TitleWidth, TitleWidth, 0);
gdCols[i].Updated := False;
mayAdjustAgain := True;
end;
end;
end;
if mayAdjustAgain then
begin
ResultGrid.Refresh;
BrowserQueryAfterScroll(DataSet);
end;
end;
{ on draw column cell }
procedure TRecordsBrowserFrameBase.GridColumnWidthAdjust(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
ColWidth, TextWidth, TitleWidth: Integer;
begin
{ ajusta a capitalização do texto das células }
(Sender as TJvDBGrid).Canvas.Pen.Color := clWhite;
(Sender as TJvDBGrid).Canvas.Rectangle(Rect);
(Sender as TJvDBGrid).Canvas.TextOut(Rect.Left+2, Rect.Top+2, NameCase(Column.Field.DisplayText));
{ ajusta as colunas de uma grade de acordo com o conteúdo das células }
gdVisibleRows := (Sender as TJvDBGrid).VisibleRowCount;
gdVisibleCols := (Sender as TJvDBGrid).VisibleColCount;
TitleWidth := MaxColSpacing + (Sender as TJvDBGrid).Canvas.TextExtent(Column.Title.Caption).cx;
TextWidth := MaxColSpacing + (Sender as TJvDBGrid).Canvas.TextExtent(NameCase(Column.Field.DisplayText)).cx;
ColWidth := Column.Width;
{$WARNINGS OFF}
if (TextWidth > gdCols[DataCol].Reverter) and (TextWidth < ColWidth) then gdCols[DataCol].Reverter := TextWidth;
if (TextWidth > ColWidth) then { texto da célula é mais largo que a coluna }
begin
gdCols[DataCol].Registered := True;
gdCols[DataCol].LastWidth := ColWidth;
gdCols[DataCol].CurrWidth := TextWidth;
gdCols[DataCol].Updated := False;
gdCols[DataCol].RecNo := BrowserQuery.RecNo;
gdCols[DataCol].Reverter := TitleWidth;
Exit;
end;
if (ColWidth < TitleWidth) then { texto da célula é menor que o título da coluna }
begin
gdCols[DataCol].Registered := True;
gdCols[DataCol].LastWidth := ColWidth;
gdCols[DataCol].CurrWidth := TitleWidth;
gdCols[DataCol].Updated := False;
gdCols[DataCol].Reverter := TitleWidth;
Exit;
end;
{$WARNINGS ON}
end;
答案 6 :(得分:0)
您好,请按照以下步骤操作。
Procedure AutoSizeColDBGrid(DBGrid:TDBGrid);
var i, ColWidth, ColTextWidth:integer;
begin
if DBGrid.DataSource.DataSet.Active then
begin
DBGrid.DataSource.DataSet.DisableControls;
for i:= 0 to DBGrid.Columns.Count-1 do
begin
ColWidth:=DBGrid.Canvas.TextWidth(DBGrid.Columns[i].Field.DisplayLabel);
DBGrid.DataSource.DataSet.First;
while not DBGrid.DataSource.DataSet.EOF do
begin
ColTextWidth:=DBGrid.Canvas.TextWidth(DBGrid.Columns[i].Field.DisplayText);
if (ColTextWidth > ColWidth) then
begin
ColWidth := ColTextWidth;
end;
DBGrid.DataSource.DataSet.Next;
end;{while}
DBGrid.Columns[i].Width:=ColWidth+10;
end;{for}
DBGrid.DataSource.DataSet.EnableControls;
DBGrid.DataSource.DataSet.First;
end;
end;
答案 7 :(得分:-1)
使用过程DbGrid1.AutoAdjustColumns
就是这样。