Ускорить процедуру изменения размера столбца сетки - PullRequest
1 голос
/ 17 ноября 2011

У меня есть процедура для автоматического изменения размера столбца в сетке, чтобы вместить самую большую строку в этом столбце.Однако, когда в сетке более 2000 записей, это занимает немного больше времени.Любые советы по ускорению этого?

//lstSKU = grid
procedure TfrmExcel.ResizeCol(const ACol: Integer);
var
  M: Integer;
  X: Integer;
  S: String;
  R: TRect;
begin
  M:= 20;
  lstSKU.Canvas.Font.Assign(lstSKU.Font);
  for X:= 1 to lstSKU.RowCount - 1 do begin
    S:= lstSKU.Cells[ACol, X];
    R:= Rect(0, 0, 20, 20);
    DrawText(lstSKU.Canvas.Handle, PChar(S), Length(S), R,
      DT_LEFT or DT_VCENTER or DT_CALCRECT);
    if R.Right > M then
      M:= R.Right;
  end;
  M:= M + 15;
  lstSKU.ColWidths[ACol]:= M;
end;

Ответы [ 2 ]

2 голосов
/ 17 ноября 2011

Это стандартная TStringGrid / TDrawGrid?

Можно выполнить итерацию, используя Canvas.TextWidth(S), чтобы измерить ширину содержимого каждой ячейки, сохранить самую большую, добавить любой отступ, а затем установить Grid.ColWidths[Col] := M;. Это вызовет одну перерисовку, если это необходимо. (В основном то, что вы делаете, не повторяя операцию рисования 2001 раз.)

procedure TfrmExcel.ResizeCol(const ACol: Integer);
var
  M, T: Integer;
  X: Integer;
  S: String;
begin
  M := 20;

  for X := 1 to lstSKU.RowCount - 1 do 
  begin
    S:= lstSKU.Cells[ACol, X];
    T := lstSKU.Canvas.TextWidth(S);
    if T > M then
      M := T;
  end;

  M := M + 15;
  lstSKU.ColWidths[ACol] := M;
end;

Если вы хотите установить ширину и высоту ячейки для размещения более крупных шрифтов или чего-то еще, используйте TextExtent вместо TextWidth; TextExtent возвращает TSize, из которого вы можете прочитать Width и Height.

1 голос
/ 18 ноября 2011

Хотя я уже ответил, я публикую окончательный код, который вы можете использовать с любой сеткой строк (TStringGrid). Он изменил размер 3000 записей с 27 столбцами за 2,3 секунды, в отличие от предыдущего среднего значения 6,4.

//AGrid = Grid containing column to be resized
//ACol = Column index of grid to be resized
//AMin = Minimum column width
procedure ResizeCol(AGrid: TStringGrid; const ACol, AMin: Integer);
var
  M, T: Integer; //M=Maximum Width; T=Current Text
  X: Integer; //X=Loop Counter
begin
  M:= AMin; //Begin with minimum width
  AGrid.Canvas.Font.Assign(AGrid.Font);
  for X:= 1 to AGrid.RowCount - 1 do begin
    T:= AGrid.Canvas.TextWidth(AGrid.Cells[ACol, X]);
    if T > M then M:= T;
  end;
  AGrid.ColWidths[ACol]:= M + AMin;
end;
...