我有一个相当大的树结构,每当用户添加或删除子节点时,树都会重新排序。这一切都很好,但我的问题是:排序后,滚动条会自动重置到树的顶部。我想这样做,以便滚动条保持(或返回)刚刚添加或删除节点的位置,这样用户无需向下滚动并在每次想要添加或删除时找到父节点东西。
我一直试图找到一些方法来做这件事,但是没有运气。有人有任何提示吗?
以下是我用于删除子节点的方法,如果有帮助的话:
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();
}
答案 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);
}