21

.NETアプリケーションでツリービューコントロールのスクロール位置を維持するにはどうすればよいですか?たとえば、ツリービューコントロールがあり、さまざまなノードを追加して下部に追加するプロセスを実行します。このプロセス中に、ツリービューをスクロールしてさまざまなノードを表示できます。問題は、プロセスが完了すると、ツリービューが一番下までスクロールすることです。

treenode.Expand()を呼び出すことが、ここで私を軌道に乗せていないようです。親ノードが展開されると、フォーカスが取得されます。

これを回避する方法はありますか?プロセスの実行中に特定のノードを見ている場合、プロセスが完了したときにそのノードが飛び回ってほしくないのです。

4

9 に答える 9

29

私は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(treeView.Handle, SB_HORZ), 
        GetScrollPos(treeView.Handle, SB_VERT));
}

スクロール位置を設定する方法:

private void SetTreeViewScrollPos(TreeView treeView, Point scrollPosition)
{
    SetScrollPos(treeView.Handle, SB_HORZ, scrollPosition.X, true);
    SetScrollPos(treeView.Handle, SB_VERT, scrollPosition.Y, true); 
}

次に、ツリーを更新するときに、次の手順を実行します。

BeginUpdate();
Point ScrollPos = GetTreeViewScrollPos(treeMain);
// write your update code here
SetTreeViewScrollPos(treeMain, ScrollPos);
EndUpdate();
于 2008-12-11T16:13:43.577 に答える
18

私はそれを理解したと思います:

  1. ツリービューの上部にあるノードを取得します。
  2. 親ノードを展開します。
  3. 以前は一番上にあったノードを表示します。
If treeNodeParent.IsExpanded = False Then
    Dim currentNode As TreeNode = TreeViewHosts.GetNodeAt(0, 0)
    treeNodeParent.Expand()
    currentNode.EnsureVisible()
End If

これを行うためのより良い方法はありますか?

于 2008-12-02T02:18:16.420 に答える
7

外部関数なしでスクロール位置を保持できる別の方法は、ツリーの 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();

ノードを追加した後、その FullPath を topNodePath に対してチェックします。

nodes.Add(node)
if ((topNodePath != null) && (node.FullPath == topNodePath))
{
    topNode = node;
}

すべてのノードを追加したら、ツリーの TopNode プロパティを更新します。

if (topNode != null)
{
    m_Tree.TopNode = topNode;
}

選択したノードと展開したノードにも同様の手法を使用します。SelectedNode は、上記の TopNode とほぼ同じように機能します。展開されたノードの場合、再帰関数を使用して子ノードをループし、展開されたノードのパスをリストに追加します。次に、子が追加された後、パスに基づいてそれらを展開します。

もちろん、同じ名前の兄弟ノードがたくさんある場合、これはうまくいかないかもしれません:-)

于 2012-05-22T02:41:42.907 に答える
1

スクロール自体が更新された場合にも同じ問題が発生しましたが、ツリービューのコンテンツがスクロールされませんでした。BeginUpdate()これは、を追加することで簡単に修正できましEndUpdate()SetScrollPos()

this.hierarchyTreeView.BeginUpdate();
SetScrollPos(this.hierarchyTreeView.Handle, SB_VERT, 5, true);
this.hierarchyTreeView.EndUpdate();
于 2011-01-11T10:23:30.773 に答える
0

これは、Stefan Koell からの美しい応答を TreeViewExtension として改訂したものです: (完全なソリューション)

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop;
using System.Windows.Media;

public static class TreeViewExtension
{
    #region Constants

    private const int ScrollBarHorizontal = 0x0;

    private const int ScrollBarVertical = 0x1;

    #endregion

    #region Public Methods and Operators

    [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
    public static extern int GetScrollPos(int hWnd, int nBar);

    public static Point ScrollPosition(this TreeView treeView)
    {
        return new Point(
            GetScrollPos((int)treeView.Handle(), ScrollBarHorizontal), 
            GetScrollPos((int)treeView.Handle(), ScrollBarVertical));
    }

    public static void ScrollTo(this TreeView treeView, Point scrollPosition)
    {
        SetScrollPos(treeView.Handle(), ScrollBarHorizontal, (int)scrollPosition.X, true);
        SetScrollPos(treeView.Handle(), ScrollBarVertical, (int)scrollPosition.Y, true);
    }

    [DllImport("user32.dll")]
    public static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw);

    #endregion

    #region Methods

    private static IntPtr Handle(this Visual treeView)
    {
        var handle = IntPtr.Zero;
        var hwndSource = PresentationSource.FromVisual(treeView) as HwndSource;
        if (hwndSource != null)
        {
            handle = hwndSource.Handle;
        }

        return handle;
    }

    #endregion
}

おそらくそれはあなたの仕事を簡素化します;-)

于 2014-08-22T13:06:22.997 に答える
0
myTreeView.Nodes[0].EnsureVisible();
于 2012-03-08T20:53:52.870 に答える
-3

最良の方法は、UpdatePanel を使用し、その中にツリービュー タグをネストすることです。例えば、

<asp:UpdatePanel id="UpdatePanel">
     <ContentTemplate>
         <asp:TreeView id="TreeView">

         </asp:TreeView>
     </ContentTemplate>
</asp:UpdatePanel>

それは私にとってはうまくいきました。あなたの問題が解決することを願っています。

于 2013-05-06T05:54:57.377 に答える