TreeView for WinForms | ComponentOne
In This Topic
    Load-On Demand
    In This Topic

    Users can use a technique called "delayed loading" where nodes are populated on demand when the user expands them. This allows the application to load faster and use resources more efficiently. The Load-On demand is an excellent alternative over fully populating each node when the application starts.

    This image shows on-demand loading in TreeView.

    The implementation below uses the event hander Expanding event, so that users can populate the node they try to expand it. In the code snippet below, we have saved the information we need to populate the node in the Tag property. Also, we add a dummy child node so the user will be able to expand this node and trigger the Expanding event that will populate the node.

    Let's see how to implement the on-demand loading in TreeView, using the following code snippet:

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' Remove items if any added at design time
        Me.C1TreeView1.Nodes.Clear()
        'Add first two levels of nodes to create a basic structure of TreeView
        ' Scan every type in the assembly
        For Each t As Type In Me.C1TreeView1.GetType().Assembly.GetTypes()
            If t.IsPublic AndAlso Not t.IsSpecialName AndAlso Not t.IsAbstract Then
                ' Add node for this type
                Dim node As C1TreeNode = New C1TreeNode()
                node.SetValue(t.Name)
                ' Save information needed to populate the node
                node.Tag = t
                Me.C1TreeView1.Nodes.Add(node)
                ' Add subnodes for properties, events, and methods
                node.Nodes.Add(CreateMemberNode("Properties", t, MemberTypes.Property))
                node.Nodes.Add(CreateMemberNode("Events", t, MemberTypes.Event))
                node.Nodes.Add(CreateMemberNode("Methods", t, MemberTypes.Method))
            End If
        Next
    
        'Handle the Expanding event to add nodes on demand
        AddHandler Me.C1TreeView1.Expanding, AddressOf Me.C1TreeView1_Expanding
    End Sub
    
    'Creating and adding a node to TreeView
    Private Function CreateMemberNode(ByVal header As String, ByVal t As Type, ByVal memberTypes As MemberTypes) As C1TreeNode
        ' Create the node
        Dim node As C1TreeNode = New C1TreeNode()
        node.SetValue(header)
        ' Save information needed to populate the node
        node.Tag = memberTypes
        ' Add a dummy node so this node can be expanded
        node.Nodes.Add(New C1TreeNode())
        node.Expanded = False
        ' Finish
        Return node
    End Function
    
    Private Sub C1TreeView1_Expanding(sender As Object, e As C1TreeViewCancelEventArgs) Handles C1TreeView1.Expanding
        ' Get the node that fired the event            
        Dim node As C1TreeNode = TryCast(e.Node, C1TreeNode)
    
        If node.Level <> 0 Then
            ' Remove dummy node
            node.Nodes.Clear()
            ' Populate the node
            Dim type As Type = CType(node.ParentCollection.Parent.Tag, Type)
            Dim memberTypes As MemberTypes = node.Tag
            Dim bf As BindingFlags = BindingFlags.Public Or BindingFlags.Instance
    
            For Each mi As MemberInfo In type.GetMembers(bf)
    
                If mi.MemberType = memberTypes Then
    
                    If Not mi.Name.StartsWith("get_") AndAlso Not mi.Name.StartsWith("set_") Then
                        Dim item As C1TreeNode = New C1TreeNode()
                        item.SetValue(mi.Name)
                        node.Nodes.Add(item)
                    End If
                End If
            Next
        End If
    End Sub
    
    private void Form1_Load(object sender, EventArgs e)
    {           
        // Remove items if any added at design time
        c1TreeView1.Nodes.Clear();
        //Add first two levels of nodes to create a basic structure of TreeView
        // Scan every type in the assembly
        foreach (Type t in c1TreeView1.GetType().Assembly.GetTypes())
        {
            if (t.IsPublic && !t.IsSpecialName && !t.IsAbstract)
            {
                // Add node for this type
                C1TreeNode node = new C1TreeNode();
                node.SetValue(t.Name);
                // Save information needed to populate the node
                node.Tag = t;
                c1TreeView1.Nodes.Add(node);
                // Add subnodes for properties, events, and methods
                node.Nodes.Add(CreateMemberNode("Properties", t, MemberTypes.Property));
                node.Nodes.Add(CreateMemberNode("Events", t, MemberTypes.Event));
                node.Nodes.Add(CreateMemberNode("Methods", t, MemberTypes.Method));
            }
        }
        //Handle the Expanding event to add nodes on demand
        c1TreeView1.Expanding += c1TreeView1_Expanding;
    }
    
    //Creating and adding a node to TreeView
    C1TreeNode CreateMemberNode(string header, Type t, MemberTypes memberTypes)
    {
        // Create the node
        C1TreeNode node = new C1TreeNode();
        node.SetValue(header);
        // Save information needed to populate the node
        node.Tag = memberTypes;
        // Add a dummy node so this node can be expanded
        node.Nodes.Add(new C1TreeNode());
        node.Expanded = false;
        // Finish
        return node;
    }
    
    private void c1TreeView1_Expanding(object sender, C1TreeViewCancelEventArgs e)
    {
        // Get the node that fired the event            
        C1TreeNode node = e.Node as C1TreeNode;
        if (node.Level != 0)
        {
            // Remove dummy node
            node.Nodes.Clear();
            // Populate the node
            Type type = (Type)node.ParentCollection.Parent.Tag;
            MemberTypes memberTypes = (MemberTypes)node.Tag;
            BindingFlags bf = BindingFlags.Public | BindingFlags.Instance;
            foreach (MemberInfo mi in type.GetMembers(bf))
            {
                if (mi.MemberType == memberTypes)
                {
                    if (!mi.Name.StartsWith("get_") && !mi.Name.StartsWith("set_"))
                    {
                        C1TreeNode item = new C1TreeNode();
                        item.SetValue(mi.Name);
                        node.Nodes.Add(item);
                    }
                }
            }
        }
    }
    
    Note: The latest WinForms .NET Edition does not include rich design-time support yet. We will enhance it in future releases.