У меня есть узлы с переменной высотой. Если высота прокрученного узла больше, чем клиентская область VST, вызов функции «ScrollIntoView (GetLast, False, False)» в первый раз делает работу отлично, и она перескакивает на конец последнего узла, который является хорошим.TVirtualStringTree: прокрутка до дна два раза приводит к переключению
Но вызов этой же функции снова вызывает прокрутку до начала последнего узла. Это какая-то особенность? Я не хочу этого, как отключить?
Я проверил функцию ScrollIntoView, чтобы понять причину. При первом вызове R.Top равен 0, поэтому он переходит в другую часть, которая дает ожидаемый результат. Но со вторым вызовом он обнаруживает, что R.Top отрицательный, и делает, если часть, которая вызывает прокрутку до начала последнего узла, который не нужен.
Любое предложение?
This is OnTimer event: (500ms)
procedure TMainForm.SyncHexLog;
begin
Try
if (HexLog.RootNodeCount <> FirpList.ComOperationCountLagged) then
begin
HexLog.RootNodeCount := FirpList.ComOperationCountLagged;
// measure for fast scroling
HexLog.ReInitNode(HexLog.GetLastNoInit(), True);
if FAutoScroll then
begin
//HexLog.ScrollToTheBottom();
HexLog.ScrollIntoView(HexLog.GetLast(), False, False);
end;
end;
Finally
End;
end;
function TBaseVirtualTree.ScrollIntoView(Node: PVirtualNode; Center: Boolean; Horizontally: Boolean = False): Boolean;
// Scrolls the tree so that the given node is in the client area and returns True if the tree really has been
// scrolled (e.g. to avoid further updates) else returns False. If extened focus is enabled then the tree will also
// be horizontally scrolled if needed.
// Note: All collapsed parents of the node are expanded.
var
R: TRect;
Run: PVirtualNode;
UseColumns,
HScrollBarVisible: Boolean;
ScrolledVertically,
ScrolledHorizontally: Boolean;
begin
ScrolledVertically := False;
ScrolledHorizontally := False;
if Assigned(Node) and (Node <> FRoot) then
begin
// Make sure all parents of the node are expanded.
Run := Node.Parent;
while Run <> FRoot do
begin
if not (vsExpanded in Run.States) then
ToggleNode(Run);
Run := Run.Parent;
end;
UseColumns := FHeader.UseColumns;
if UseColumns and FHeader.FColumns.IsValidColumn(FFocusedColumn) then
R := GetDisplayRect(Node, FFocusedColumn, not (toGridExtensions in FOptions.FMiscOptions))
else
R := GetDisplayRect(Node, NoColumn, not (toGridExtensions in FOptions.FMiscOptions));
// The returned rectangle can never be empty after the expand code above.
// 1) scroll vertically
if R.Top < 0 then // <==== what is the purpose of this if, I need always else part
begin
if Center then
SetOffsetY(FOffsetY - R.Top + ClientHeight div 2)
else
SetOffsetY(FOffsetY - R.Top);
ScrolledVertically := True;
end
else
if (R.Bottom > ClientHeight) or Center then
begin
HScrollBarVisible := (ScrollBarOptions.ScrollBars in [ssBoth, ssHorizontal]) and
(ScrollBarOptions.AlwaysVisible or (Integer(FRangeX) > ClientWidth));
if Center then
SetOffsetY(FOffsetY - R.Bottom + ClientHeight div 2)
else
SetOffsetY(FOffsetY - R.Bottom + ClientHeight);
// When scrolling up and the horizontal scroll appears because of the operation
// then we have to move up the node the horizontal scrollbar's height too
// in order to avoid that the scroll bar hides the node which we wanted to have in view.
if not UseColumns and not HScrollBarVisible and (Integer(FRangeX) > ClientWidth) then
SetOffsetY(FOffsetY - GetSystemMetrics(SM_CYHSCROLL));
ScrolledVertically := True;
end;
if Horizontally then
// 2) scroll horizontally
ScrolledHorizontally := ScrollIntoView(FFocusedColumn, Center);
end;
Result := ScrolledVertically or ScrolledHorizontally;
end;
Возможный дубликат, см http://stackoverflow.com/questions/2839397/how-to-reliably-scroll-virtual-treeview-to-the-bottom –
К сожалению, нет -/ –
цель этого " если "ветвь очевидна: функция ScrollIntoView не предназначена для * только * прокрутки до последнего узла. Он предназначен для прокрутки на * любой * узел, включая узлы, которые находятся выше текущего видового экрана. –