排序后滚动条重置到treeView的顶部?

时间:2015-06-10 16:22:26

标签: c# .net winforms

我有一个相当大的树结构,每当用户添加或删除子节点时,树都会重新排序。这一切都很好,但我的问题是:排序后,滚动条会自动重置到树的顶部。我想这样做,以便滚动条保持(或返回)刚刚添加或删除节点的位置,这样用户无需向下滚动并在每次想要添加或删除时找到父节点东西。

我一直试图找到一些方法来做这件事,但是没有运气。有人有任何提示吗?

以下是我用于删除子节点的方法,如果有帮助的话:

private void RemoveFromCategoryEvent(object sender, EventArgs e)
{
  SuspendLayout();

  if (treeViewCategories.SelectedNode != null)
  {
    TreeNode treeNode = treeViewCategories.SelectedNode;
    TreeNode parentNode = treeNode.Parent;
    if ((settingGroup != null) && (settingGroup.GroupRootCategory != null)
        && (settingGroup.GroupRootCategory.Settings != null) && (treeNode.Tag is ISetting)
        && (parentNode.Tag is IDeviceSettingCategory))
    {
      ISetting currentSetting = treeNode.Tag as ISetting;
      (parentNode.Tag as IDeviceSettingCategory).Settings.Remove(currentSetting);
      treeNode.Remove();

      settingGroup.GroupRootCategory.Settings.Add(currentSetting);
      TreeNode settingNode = rootCategoryNode.Nodes.Add(currentSetting.ShortName);
      settingNode.Tag = currentSetting;

      settingNode.ImageIndex = Utilities.SettingCategoryChildImage;
      settingNode.SelectedImageIndex = Utilities.SettingCategoryChildImage;

      treeViewCategories.Sort(); //scrollbar reset happens here
    }
  }

  ResumeLayout();
}

1 个答案:

答案 0 :(得分:2)

您可以使用P / Invoke获取当前滚动位置,保存它,然后在排序后将其恢复。

您需要以下API调用:

[DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
public static extern int GetScrollPos(int hWnd, int nBar);

[DllImport("user32.dll")]
static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw);

private const int SB_HORZ = 0x0;
private const int SB_VERT = 0x1;

获取当前位置:

private Point GetTreeViewScrollPos(TreeView treeView)
{
    return new Point(
        GetScrollPos((int)treeView.Handle, SB_HORZ), 
        GetScrollPos((int)treeView.Handle, SB_VERT));
}

设置位置:

private void SetTreeViewScrollPos(TreeView treeView, Point scrollPosition)
{
    SetScrollPos((IntPtr)treeView.Handle, SB_HORZ, scrollPosition.X, true);
    SetScrollPos((IntPtr)treeView.Handle, SB_VERT, scrollPosition.Y, true); 
}