views:

108

answers:

0

I have a Treeview with a lot of nodes. If I switch a node, the scrollbar of the treeview is set to the bottom.

To keep the switched node visible I use node.EnsureVisible(). But I don't like this method a lot, because it is confusing the end user.

So I look further and now I use the code which is supplied here:

http://stackoverflow.com/questions/332788/maintain-scroll-position-of-treeview

The problem of this code is, the content of the treeview doesn't scroll. The scrollbar is at the right position, but the content doesn't do anything. Until I click on the scrollbar (I don't scroll) the content becomes visible.

So, what I want to achieve is when a treenode is switched I want to maintain the scroll position.

Code that switches a node. In this case a node downwards. The function look like this:

// Check a node is selected
if (tvCategories.SelectedNode == null)
    return;

// The first node may not be moved
if (IsNewRootCategorySelected())
    return;

Point ScrollPos = GetTreeViewScrollPos(tvCategories);

// Declare and instantiate the parent node
TreeNodeCollection parent = null;
if (tvCategories.SelectedNode.Parent == null)
    parent = tvCategories.Nodes;
else
    parent = tvCategories.SelectedNode.Parent.Nodes;

TreeNode selectedNode = tvCategories.SelectedNode;
int index = selectedNode.Index;

// Check there's a next node at the same level
if (tvCategories.SelectedNode.NextNode == null)
{
    // Check if the parent node has a next node
    if (tvCategories.SelectedNode.Parent != null && tvCategories.SelectedNode.Parent.NextNode != null)
    {
        // get the destination parent
        TreeNode destParent = selectedNode.Parent.NextNode;

        // remove selected node from tree view
        parent[index].Remove();

        // If selected node is a category, add the node to the first index
        if (selectedNode.Tag is Category)
        {
            destParent.Nodes.Insert(0, selectedNode);
        }

        // If selected node is a question, add node below last category
        if (selectedNode.Tag is Question)
        {
            int newIndex = 0;

            // Loop through collection to find last category
            for (int i = destParent.Nodes.Count - 1; i >= 0; i--)
            {
                if (destParent.Nodes[i].Tag is Category)
                {
                    newIndex = i + 1;
                    break;
                }
            }

            destParent.Nodes.Insert(newIndex, selectedNode);
        }

        selectedNode.Expand();
    }
}
else
{
    // Switch nodes in same level

    tvCategories.BeginUpdate();
    _loading = true;

    if (selectedNode.Tag is Category)
    {
        // Only switch category downwards when next node is a catgory
        if (selectedNode.NextNode.Tag is Category)
        {
            // Perform switch
            TreeNode switchNode = parent[index + 1];

            parent[index + 1].Remove();
            parent[index].Remove();

            parent.Insert(index, switchNode);
            parent.Insert(index + 1, selectedNode);
        }
        else if (selectedNode.NextNode.Tag is Question)
        {
            // Make the switch to another node below
            if (selectedNode.Parent.NextNode != null)
            {
                // Parent is always a category

                TreeNode categoryParent = selectedNode.Parent.NextNode;

                // Remove selected node from current parent
                parent.Remove(selectedNode);

                // Insert selected node
                categoryParent.Nodes.Insert(0, selectedNode);

            }
        }
    }
    if (selectedNode.Tag is Question)
    {
        if (selectedNode.NextNode.Tag is Question)
        {
            // Perform switch
            TreeNode switchNode = parent[index + 1];

            parent[index + 1].Remove();
            parent[index].Remove();

            parent.Insert(index, switchNode);
            parent.Insert(index + 1, selectedNode);
        }
    }
}

tvCategories.EndUpdate();
// Set focus
tvCategories.Focus();

tvCategories.SelectedNode = selectedNode;
SetTreeViewScrollPos(tvCategories, ScrollPos);