Dynamic Treeview Height

My treeview is collapsed when I load it so it's about 100x150 pixels big. When it is expanded, I want the treeview to show all of the expanded nodes.

In order to do that the form would need to get larger as the treeview gets larger, right? I'm new at VB.net and I was trying to find a "GrowOnly" property in the treeview but I couldn't find one... Has anyone ever done this?

Answers


Handle AfterExpand / AfterCollapse Events

Add the event handlers AfterExpand and AfterCollapse to make the treeview react to the expanding / collapsing of the nodes. I hardcoded the padding for this example, but essentially this is just the height of the menus, buttons, etc that will be used to resize the form.

Private Sub Rapports_tvAllReports_AfterExpand(sender As Object, e As System.Windows.Forms.TreeViewEventArgs) Handles Rapports_tvAllReports.AfterExpand, Rapports_tvAllReports.AfterCollapse
    Dim Padding As Integer = 140 'Customize this, basically accounts for all buttons or menus included in the form which nests the treeview
    Dim TreeViewHeight As Integer = GetOpenedNodesRecursively(Rapports_tvAllReports)

    If formWindow = FormWindowState.Normal Then Me.Size = New Size(345, TreeViewHeight + Padding)
End Sub

All we do is increment the Y and set that new Y to the form. In order for the treeview to correctly resize along with the form, anchor it to the top and bottom.

Recursively go through nodes

This function will go through the root nodes and call a recursive function on the opened nodes.

Private Function GetOpenedNodesRecursively(ByVal aTreeView As TreeView)
    Dim Y As Integer = 0

    'Go through each node of the treeview (first level)
    For Each n As TreeNode In aTreeView.Nodes
        Y += Rapports_tvAllReports.ItemHeight

        'If the user expands a node, recursively increment the Y
        If n.IsExpanded Then Y += RecursiveYIncrement(n)
    Next

    Return Y
End Function

Now just keep incrementing the TreeViewHeight using the recursive function that will return the height (Y) of all nodes that are expanded in the current tree view.

Private Function RecursiveYIncrement(ByVal n As TreeNode)
    Dim Y As Integer = 0

    'Go through each node of the treeview (first level)
    For Each aNode As TreeNode In n.Nodes
        Y += Rapports_tvAllReports.ItemHeight

        'If the user expands a node, recursively increment the Y
        If aNode.IsExpanded Then Y += RecursiveYIncrement(aNode)
    Next

    Return Y
End Function
Visual Reproduction

Here is how it looks when we're done:

We start with a collapsed tree view

We can then expand some nodes and the form will grow accordingly

And then we can re-collapse the nodes and expand more, the form adjusts again!

Forgive me for the French in the screenshots, it's the norm here in Quebec... We're obligated to do so!


You could trap the BeforeExpand and AfterExpand TreeView events to detect when the user changes the height of the node area. In that event handler, you need to find the bottom of the last node (using the Bounds property), then you finally need to change the height of the form.

Ensure that the TreeView's Anchor property includes both top and bottom, so that it grows with the form.

Of course the form has to be taller than than the TreeView. The bottom node's Bounds.Bottom property won't be exactly the bottom of the treeview, so my example below inflates this first by the height difference between the TreeView and form, then secondly by the difference between the client height of the TreeView, and the total height of the TreeView. It works correctly at my end.

You'd assign this same method to both the BeforeExpand and AfterExpand events. Note that it finds the last node by iterating through the nodes to find the bottom one; you'd want to check to make sure that this is guaranteed to give you the last node.

EDIT: You need to tell the tree to scroll to display the first node before starting any of this, for it to work consistently: hence the EnsureVisible() call.

Private Sub TreeView1_BeforeOrAfterExpand(sender As Object, e As TreeViewEventArgs) Handles TreeView1.AfterExpand, TreeView1.AfterCollapse
    Dim lastNode As TreeNode = TreeView1.Nodes(0)

    TreeView1.Nodes(0).EnsureVisible()

    While lastNode.LastNode IsNot Nothing And lastNode.IsExpanded
        lastNode = lastNode.LastNode
    End While

    Dim diffBetweenFormAndTreeview As Integer = Me.Height - TreeView1.Height
    Dim diffBetweenTreeviewTotalAndClient As Integer = TreeView1.Height - TreeView1.ClientSize.Height
    Me.Height = lastNode.Bounds.Bottom + diffBetweenFormAndTreeview + diffBetweenTreeviewTotalAndClient
End Sub

Need Your Help

Not getting the correct count in SQL

sql sql-server-2005 tsql

I am totally new to SQL. I have a simple select query similar to this:

Monitor Android system settings values

android settings listener

I want to watch a system setting and get notified when its value changes. The Cursor class has a setNotificationUri method which sounded nice, but it doesn't work and coding it also feels strange...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.