Brad
Brad

Reputation: 21210

Scroll selected TreeView node into view

I have a System.Windows.Forms.TreeView docked inside a panel. I am setting a node selected programmatically. What method or property would I use to have the treeview scroll the selected into view?

Upvotes: 26

Views: 23970

Answers (5)

Kim Crosser
Kim Crosser

Reputation: 433

What I found worked reliably was:

  1. Expand the desired node
  2. Force scroll to the END by EnsureVisible() on the Last node of the tree
  3. Scroll back to the desired node by EnsureVisible() on that node

This results in the desired node and the expanded children being placed at the top of the treeview display area.

        TVFolders.BeginUpdate();
        TVFolders.Nodes.Clear();
        TreeNode tn = new TreeNode()
        {
            Text = RootFolderPath,
            Name = RootFolderPath
        };
        TVFolders.Nodes.Add(tn);
        //      load the treeview (also tracks the last node added to the tree as lastNode)
        PopulateTreeView(TVFolders.Nodes[0], RootFolderPath, 6, true);
        //      if user/caller has specified a start path, select and expand it
        if (_SelectedPath != null)
        {
            //      find the node corresponding to the requested path
            TreeNode[] tns = TVFolders.Nodes.Find(_SelectedPath, true);
            //      assumes first return is the "best" one
            if (tns.Length > 0)
            {
                //      select the requested node
                TVFolders.SelectedNode = tns[0];
                //      expand to show children
                TVFolders.SelectedNode.Expand();
                //      scroll to the last node on the tree (may push our node off top)
                if (lastNode != null)
                {
                    lastNode.EnsureVisible();
                }
                //      scroll to our node, which will now be at the top of the display area
                TVFolders.SelectedNode.EnsureVisible();
            }
        }
        TVFolders.Visible = true;
        TVFolders.EndUpdate();

Upvotes: 0

Joaquim Varandas
Joaquim Varandas

Reputation: 31

To ensure the visibility of selected item:

private void EnsureItemVisible()
{
    if(treeView1.SelectedNode == null)
    {
        return;
    }

    for (int i = treeView1.SelectedNode.Index + treeView1.VisibleCount / 2; i >= 0; i--)
    {
        if (treeView1.Nodes.Count > i && treeView1.Nodes[i] != null)
        {
            treeView1.Nodes[i].EnsureVisible();
            break;
        }
    }

    for (int i = treeView1.SelectedNode.Index - treeView1.VisibleCount / 2; i < treeView1.Nodes.Count; i++)
    {
        if (i >= 0 && treeView1.Nodes[i] != null)
        {
            treeView1.Nodes[i].EnsureVisible();
            break;
        }
    }
}

Handle the TreeView selection has been changed:

private void TreeView_AfterSelect(object sender, TreeViewEventArgs e)
{   
    EnsureItemVisible();
}

Upvotes: 2

Folkien
Folkien

Reputation: 41

I also had issues with this and figured out that treeview.ExpandAll() ignores the EnsureVisible() effect and avoids the scrolling to the node position.

Just call EnsureVisible() after ExpandAll() if you want a full expanded tree with the scroll on the node you've selected.

Upvotes: 1

27k1
27k1

Reputation: 2369

I had some issues with node.EnsureVisible() not working for trees with only one level of nodes.

To fix this use the BindingIndex to identify the node selected. Then the node selected will be scrolled in view.

The example shows myTable from a LINQ query.

node.BindingIndex = Convert.ToInt32(mytable.Id);

I hope this helps some of you.

Upvotes: 0

Marc Gravell
Marc Gravell

Reputation: 1064244

node.EnsureVisible();

for example:

if(treeView.SelectedNode != null) treeView.SelectedNode.EnsureVisible();

(see MSDN)

Upvotes: 43

Related Questions