当前位置:  开发笔记 > 编程语言 > 正文

保持树视图的滚动位置

如何解决《保持树视图的滚动位置》经验,为你挑选了3个好方法。

如何在.NET应用程序中维护树视图控件的滚动位置?例如,我有一个树视图控件,并通过添加各种节点的过程将它们固定到底部.在此过程中,我可以滚动树视图并查看不同的节点.问题是当进程完成时,树视图滚动到最底部.

似乎调用treenode.Expand()是让我偏离轨道的原因.展开父节点时,它将获得焦点.

有没有解决的办法?如果我在进程运行时查看特定节点,我不希望它在进程完成时跳转到我身边.



1> Stefan Koell..:

我不是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();



2> Matt Hanson..:

我想我弄清楚了:

    将节点放在树视图的顶部.

    展开父节点.

    使之前位于顶部的节点可见.

If treeNodeParent.IsExpanded = False Then
    Dim currentNode As TreeNode = TreeViewHosts.GetNodeAt(0, 0)
    treeNodeParent.Expand()
    currentNode.EnsureVisible()
End If

这是一个更好的方法吗?


我建议的唯一更好的方法是用`TreeViewHosts.TopNode`替换`TreeViewHosts.GetNodeAt(0,0)`然后你可能想用`TreeViewHosts.TopNode = currentNode`替换`currentNode.EnsureVisible()`但是,他们应该有效地做同样的事情.

3> Josh Stribli..:

在没有外部函数的情况下保存滚动位置的另一种方法是使用树的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完全一样.对于扩展节点,我使用递归函数来遍历子节点,并将扩展节点的路径添加到列表中.然后在添加子项后根据其路径展开它们.

当然,如果你有很多同名的兄弟节点,这可能也行不通:-)

推荐阅读
mobiledu2402851373
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有