如何在.NET应用程序中维护树视图控件的滚动位置?例如,我有一个树视图控件,并通过添加各种节点的过程将它们固定到底部.在此过程中,我可以滚动树视图并查看不同的节点.问题是当进程完成时,树视图滚动到最底部.
似乎调用treenode.Expand()是让我偏离轨道的原因.展开父节点时,它将获得焦点.
有没有解决的办法?如果我在进程运行时查看特定节点,我不希望它在进程完成时跳转到我身边.
我不是VB的人,但在C#中我是这样做的:
一些Win32原生函数:
[DllImport("user32.dll", CharSet = CharSet.Unicode)] public static extern int GetScrollPos(IntPtr hWnd, int nBar); [DllImport("user32.dll", CharSet = CharSet.Unicode)] public 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); }
然后,在更新树时,请执行以下操作:
BeginUpdate(); Point ScrollPos = GetTreeViewScrollPos(treeMain); // write your update code here SetTreeViewScrollPos(treeMain, ScrollPos); EndUpdate();
我想我弄清楚了:
将节点放在树视图的顶部.
展开父节点.
使之前位于顶部的节点可见.
If treeNodeParent.IsExpanded = False Then Dim currentNode As TreeNode = TreeViewHosts.GetNodeAt(0, 0) treeNodeParent.Expand() currentNode.EnsureVisible() End If
这是一个更好的方法吗?
在没有外部函数的情况下保存滚动位置的另一种方法是使用树的TopNode属性...
TopNode获取或设置树视图控件中的第一个完全可见的树节点.
如果您只想展开节点并让它保留顶部节点:
TreeNode topNode = m_Tree.TopNode; treenode.Expand(); m_Tree.TopNode = topNode;
否则,如果要重建树(例如刷新文件结构),则可以使用以下方法...
在清除树之前,存储顶级节点的完整路径:
string topNodePath = null; TreeNode topNode = null; if (m_Tree.TopNode != null) { topNodePath = m_Tree.TopNode.FullPath; } m_Tree.Clear();
添加节点后,请针对topNodePath检查其FullPath:
nodes.Add(node) if ((topNodePath != null) && (node.FullPath == topNodePath)) { topNode = node; }
添加所有节点后,更新树的TopNode属性:
if (topNode != null) { m_Tree.TopNode = topNode; }
我对选定和扩展节点使用类似的技术.SelectedNode几乎与上面显示的TopNode完全一样.对于扩展节点,我使用递归函数来遍历子节点,并将扩展节点的路径添加到列表中.然后在添加子项后根据其路径展开它们.
当然,如果你有很多同名的兄弟节点,这可能也行不通:-)