dummzeuch 1517 Posted June 26, 2019 I have got a VirtualStringTree in grid mode and I would like to autosize the columns so that they are wide enough to display the column text and the column header. Calling vst.Header.AutoFitColumns works for the column text but not for the header. I would have thought that this question has been asked and answerted before, but my Google fu is becoming ever weaker. I found lots of hints on how to fit the column text, but not the header. Share this post Link to post
dummzeuch 1517 Posted June 28, 2019 Since apparently nobody has ans answer and I was unable to find any settings or method to achieve this, here is the code I used: procedure TMyForm.ResizeTree(_vst: TVirtualStringTree); var c: UInt32; ws: WideString; cnv: TCanvas; Fnt: TFont; ThisWidth: UInt32; MinWidth: UInt32; Node: PVirtualNode; r: TRect; s: TSize; begin cnv := _vst.Canvas; for c := 0 to _vst.Header.Columns.Count - 1 do begin ws := _vst.Header.Columns[c].Text; GetTextExtentPoint32W(cnv.Handle, PWideChar(ws), Length(ws), s); MinWidth := s.cx + 10; Fnt := _vst.Font; Node := _vst.RootNode.FirstChild; while Assigned(Node) do begin _vst.GetTextInfo(Node, c, Fnt, r, ws); ThisWidth := r.Right - r.Left + 10; if MinWidth < ThisWidth then MinWidth := ThisWidth; Node := Node.NextSibling; end; _vst.Header.Columns[c].Width := MinWidth; end; end; It's probably not perfect but it worked for me (until I dropped the VirtualStringTree because it just added too much complexity for what I wanted to achieve, and replaced it with the much simpler TdzVirtualTreeView which I had to extend for my use case.) I particular I don't like the constant 10 pixels in the code. Share this post Link to post
Mike Torrettinni 198 Posted June 28, 2019 I customized function TBaseVirtualTree.GetMaxColumnWidth that is used in AutoFitColumns - what I use to autosize columns: // start with Column Caption width if FHeader.FColumns[Column].Text <> '' then begin GetTextExtentPoint32W(Canvas.Handle, PWideChar(FHeader.FColumns[Column].Text), Length(FHeader.FColumns[Column].Text), vSize); Result := vSize.cx + 20; // Margin end; Which takes into account the Column caption and adds it to the starting Result value, before it gets to calculating column width based on text. I put it before this line: while Assigned(Run) and not OperationCanceled do Works good for my usage. Share this post Link to post