Tutorial :How can Virtual Treeview control be made to always scroll by lines?


The Virtual Treeview scrolls vertically by pixels, unlike the way the standard Delphi grids, TListView and TTreeView (or most of the other such controls that I am aware of) scroll by line and keep a full line visible at the top of the control at all times. When I use the cursor keys to navigate, then depending on direction either the first or the last line is completely visible. When scrolling with the mouse there is no alignment whatsoever.

This behaviour can be observed for example with the Structure window in Delphi 2007 and 2009.

Is there any way to set the many properties to have the behaviour of the standard windows controls? Or is there a set of patches somewhere to achieve this?


You could intercept the TBaseVirtualTree.OnScroll event and use the virtual treeview's canvas's return value for textheight('M') as the amount to change TBaseVirtualTree.offsety in order to increment (scroll up) or decrement (scroll down). Could also test to ensure that pre-scroll position modulus textheight('M') is zero (to avoid scrolling by the right amount from the wrong position).

Alternatively, this post on the Virtual Treeview forum suggests another approach: hide the virtual treeview's native scroll bars with VCL scroll bars and then do the scrolling yourself (trapping VCL scroll events and programmatically scrolling the virtual treeview).


This is what I came up with the help of Argalatyr, looks like it does what I want it to:

procedure TForm1.FormCreate(Sender: TObject);  begin    VirtualStringTree1.ScrollBarOptions.VerticalIncrement :=      VirtualStringTree1.DefaultNodeHeight;  end;    procedure TForm1.VirtualStringTree1Resize(Sender: TObject);  var    DY: integer;  begin    with VirtualStringTree1 do begin      DY := VirtualStringTree1.DefaultNodeHeight;      BottomSpace := ClientHeight mod DY;      VirtualStringTree1.OffsetY := Round(VirtualStringTree1.OffsetY / DY) * DY;    end;  end;    procedure TForm1.VirtualStringTree1Scroll(Sender: TBaseVirtualTree; DeltaX,    DeltaY: Integer);  var    DY: integer;  begin    if DeltaY <> 0 then begin      DY := VirtualStringTree1.DefaultNodeHeight;      VirtualStringTree1.OffsetY := Round(VirtualStringTree1.OffsetY / DY) * DY;    end;  end;  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »