0

プロジェクトの継続は次の場所で開始されました。

DBGrid(または他の同様の)列の幅をその内容に応じて自動調整/スケーリングするにはどうすればよいですか?

@alzaimarの回答を使用して、コンテンツの幅に応じて列を自動調整しましたが、幅を増やす方法を教えてくれましたが、減らす方法は教えてくれなかったので、上記のようにコードを補完しました。

procedure TRecordsBrowserFrameBase.JvDBGrid2DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  h, p, g, r, w, t : Integer;
const
  colSpc = 10;
begin
{ ajusta as colunas de uma grade de acordo com o conteúdo das células }
  h := Column.DropDownRows;
  p := (Sender as TJvDBGrid).CurrentDrawRow;
  g := Column.Width;
  r := (Sender as TJvDBGrid).VisibleRowCount;
  w := colSpc + (Sender as TJvDBGrid).Canvas.TextExtent(Column.Field.DisplayText).cx;
  t := colSpc + (Sender as TJvDBGrid).Canvas.TextExtent(Column.Title.Caption).cx;
{$WARNINGS OFF}
  // increase column width if needed
  if (w > g) then Column.Width := w;
  if (g < t) then Column.Width := t;
  if (p < r) and (h < w) then Column.DropDownRows := w;
  // decrease column size if needed (10th line)
  if (p = r) then
  begin
    h := Column.DropDownRows;
    g := Column.Width;
    if (h > t) and (h < g) then Column.Width := Column.DropDownRows;
    Column.DropDownRows := 0;
  end;
{$WARNINGS ON}
end;

したがって、下矢印キーでスクロールすると、次の図に示すように、選択した行の色が常に正しい位置にあるとは限りません。

ここに画像の説明を入力してください

私が間違っていることは何ですか?

4

1 に答える 1

1

このソリューションは、スクロールバーの有無に関係なく、すべての列をその内容に応じて拡大または縮小し、選択したセル描画の誤動作とレコードポインタの誤動作を修正します。

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;
于 2012-11-19T22:17:17.677 に答える