C# 排序后是否将滚动条重置到树状视图的顶部?
我有一个相当大的树结构,每当用户添加或删除子节点时,树都会重新排序。这一切都很好,但我的问题是:排序后,滚动条会自动重置到树的顶部。我想让滚动条保持(或返回)刚刚添加或删除节点的位置,这样用户就不必每次添加或删除内容时都向下滚动并查找父节点 一段时间以来,我一直在想办法做到这一点,但运气不好。有人有什么建议吗 以下是我用于删除子节点的方法(如果有帮助):C# 排序后是否将滚动条重置到树状视图的顶部?,c#,.net,winforms,C#,.net,Winforms,我有一个相当大的树结构,每当用户添加或删除子节点时,树都会重新排序。这一切都很好,但我的问题是:排序后,滚动条会自动重置到树的顶部。我想让滚动条保持(或返回)刚刚添加或删除节点的位置,这样用户就不必每次添加或删除内容时都向下滚动并查找父节点 一段时间以来,我一直在想办法做到这一点,但运气不好。有人有什么建议吗 以下是我用于删除子节点的方法(如果有帮助): private void RemoveFromCategoryEvent(object sender, EventArgs e) { Su
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();
}
您可以使用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);
}
获取当前位置:
[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);
}
设置位置:
[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);
}
回答得很好。这就成功了。非常感谢你,布拉德利!:)