2

我有可变高度节点。如果滚动节点高度大于 VST 客户区,第一次调用“ScrollIntoView(GetLast, False, False)”函数可以完美地完成工作,它会跳转到最后一个节点的末尾,这很好。

但是再次调用相同的函数会导致滚动到最后一个节点的开头。这是一种功能吗?我不想要这个,如何禁用?

我检查了 ScrollIntoView 函数以了解原因。第一次调用 R.Top 为 0,因此它分支到产生预期结果的 else 部分。但是在第二次调用时,它发现 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;
4

1 回答 1

1

我想是时候使用新的 delphi 功能了,比如类助手:p 我在 main.pas 中写了一些简单的东西,它看起来很有效,但我不确定它是否会涵盖所有情况。

  TBaseVirtualTreeHelper = class helper for TBaseVirtualTree
  public
    Procedure ScrollToTheBottom();
  end;

{ TBaseVirtualTreeHelper }
procedure TBaseVirtualTreeHelper.ScrollToTheBottom;
Var
  Node: PVirtualNode;
  R: TRect;

begin
  Node := Self.GetLast();

  if Assigned(Node) and (Node <> Self.FRoot) then
  begin
    R := GetDisplayRect(Node, NoColumn, True);

    if (R.Bottom > Self.ClientHeight) then
    begin
      Self.SetOffsetY(Self.FOffsetY - R.Bottom + Self.ClientHeight);
    end;
  end;
end;
于 2012-04-15T12:50:39.137 回答