Resetting scroll up to top of treeView after sorting?
I have a fairly large tree structure and whenever the user adds or removes a child node, the tree is re-sorted. This all works very well, but my problem is this: after sorting, the scrollbar is automatically reset at the top of the tree. I would like to make it so that the scrollbar holds (or returns) the position where the node was added or removed, so the user doesn't have to scroll down and find the parent node every time they want to add or remove something.
I've been trying to find a way to do this for some time, but have had no luck. Anyone have any hints?
Here is the method I use to remove the child node if it helps:
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();
}
source to share
You can use P / Invoke to get the current scroll position, save it, and then restore it after sorting.
You will need the following API calls:
[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;
Getting the current position:
private Point GetTreeViewScrollPos(TreeView treeView)
{
return new Point(
GetScrollPos((int)treeView.Handle, SB_HORZ),
GetScrollPos((int)treeView.Handle, SB_VERT));
}
Position setting:
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);
}
source to share