Как автоматически определить размер охватываемого столбца в TVirtualStringTree?


У меня есть простой пример VirtualStringTree (VST) с 4 столбцами и во 2-м или 3-м столбце я мог бы иметь больше текста, который соответствует ширине столбца по умолчанию. У меня есть hoAutoSpanColumns включен, так что большой текст будет перекрывать другие столбцы, если они пусты. Это хорошо работает. Проблема заключается в том, что текст во 2-й или 3-й колонке должен охватывать всю длину VST. В этом случае большие столбцы простираются только до конца последнего (4-го) столбца.

Вот как 2-й столбец в строке 3 охватывает только над 3-м и 4-м столбцами, а затем он останавливается на ширине 4-го столбца:

Введите описание изображения здесь

Если я использую AutoFitColumns для автоматического размера 2-го столбца:

VST1.Header.AutoFitColumns(false, smaUseColumnOption,1,1);

Затем он толкает 3-й и 4-й столбцы, так что они начинаются в конце 2-го столбца:

Введите описание изображения здесь

Но мне нужно, чтобы 3-я и 4-я колонны оставались на тех же позициях, как это:

Введите описание изображения здесь

Есть ли способ автоматически вписать 2-й столбец в текст, но сохранить 3-й и 4-й столбцы на одном уровне позиции, какими они были изначально?

1 4

1 ответ:

В настоящее время нет встроенного способа автоматического добавления заголовка к тексту растянутого столбца. Для автоматического изменения размера данного столбца, чтобы увидеть весь объемный текст, вы можете написать такой код (для одного узла). Обратите внимание, что функция autospan в VT в настоящее время не поддерживает чтение RTL (поэтому этот код также не поддерживает):

type
  TVirtualStringTree = class(VirtualTrees.TVirtualStringTree)
  protected
    function GetSpanColumn(Node: PVirtualNode): TColumnIndex; virtual;
  public
    procedure AutoFitSpanColumn(DestColumn: TColumnIndex; Node: PVirtualNode);
  end;

implementation

{ TVirtualStringTree }

function TVirtualStringTree.GetSpanColumn(Node: PVirtualNode): TColumnIndex;
begin
  { this returns visible span column for the given node, InvalidColumn otherwise }
  Result := Header.Columns.GetLastVisibleColumn;
  while ColumnIsEmpty(Node, Result) and (Result <> InvalidColumn) do
    Result := Header.Columns.GetPreviousVisibleColumn(Result);
end;

procedure TVirtualStringTree.AutoFitSpanColumn(DestColumn: TColumnIndex; Node: PVirtualNode);
var
  ColsWidth: Integer;
  SpanWidth: Integer;
  SpanOffset: Integer;
  SpanColumn: TColumnIndex;
begin
  SpanColumn := GetSpanColumn(Node);

  if SpanColumn <> InvalidColumn then
  begin
    { get the total width of the header }
    ColsWidth := Header.Columns.TotalWidth;
    { get the width of the span text cell as it would be autosized }
    SpanWidth := DoGetNodeWidth(Node, SpanColumn) + DoGetNodeExtraWidth(Node, SpanColumn) +
      DoGetCellContentMargin(Node, SpanColumn).X + Margin;
    { and get the left position of the span cell column in header }
    SpanOffset := Header.Columns[SpanColumn].GetRect.Left;
    { now, the width of the autosized column we increase by the subtraction of the fully
      visible span cell width and all columns width increased by offset of the span cell
      column; in other words, we'll just increase or decrease width of the DestColumn to
      the difference of width needed for the span column to be fully visible, or "fit" }
    Header.Columns[DestColumn].Width := Header.Columns[DestColumn].Width +
      SpanWidth - ColsWidth + SpanOffset;
  end;
end;