Search code examples
c#vb.nettreeviewrevision

Populate file revision to treeview


I try to populate list of file revision to treeview. I have a list of revision file like a below.

1.17
1.17.1.1
1.17.1.2
1.17.1.2.1.1    
1.17.1.2.1.2
1.17.1.2.1.2.1.1    
1.17.1.2.1.2.1.2
1.17.1.2.1.2.1.3
1.17.1.2.1.2.1.3.1.1
1.17.1.2.1.2.1.3.1.2
1.17.1.2.1.2.1.3.2.1
1.17.1.2.1.2.1.4    
1.17.1.2.1.2.1.5
1.17.1.2.1.2.1.5.1.1
1.17.1.2.1.2.1.5.1.2
1.17.1.2.1.2.1.5.1.2.1.1
1.17.1.2.1.3
1.17.1.2.1.4
1.18
1.19

Now, I would like to populate it like a

1.17
    1.17.1.1
    1.17.1.2
        1.17.1.2.1.1    
        1.17.1.2.1.2
            1.17.1.2.1.2.1.1    
            1.17.1.2.1.2.1.2
            1.17.1.2.1.2.1.3
                1.17.1.2.1.2.1.3.1.1
                1.17.1.2.1.2.1.3.1.2
                1.17.1.2.1.2.1.3.2.1    
            1.17.1.2.1.2.1.4    
            1.17.1.2.1.2.1.5    
                1.17.1.2.1.2.1.5.1.1
                1.17.1.2.1.2.1.5.1.2    
                    1.17.1.2.1.2.1.5.1.2.1.1        
        1.17.1.2.1.3
        1.17.1.2.1.4                        
1.18
1.19

My idea is classified it by level

1.17         -> level 1
1.17.1.1     -> level 2
1.17.1.2     -> level 2
1.17.1.2.1.1 -> level 3
...

Then I use switch case to populate it to treeview

if level = 1 then parent node
else if level = 2 then child node
else if level = 3 then grandchild node
...

However, I don't know is it a right way to achieve my purpose. Is there any better way to do that?

Any help are appreciate and thanks so much


Solution

  • You can take advantage of the repeated pattern of the TreeNodes paths ( #.# ). Create an array of them using the RegEx. If there is only one item in the array, then the path is of the root node, otherwise string join the array except the last item (to concat the parent's name) and use the TreeView.Nodes.Find(..) function to find the parent node of each path.

    C#

    private void PopulateTree(IEnumerable<string> paths)
    {
        treeView1.BeginUpdate();
        treeView1.Nodes.Clear();
    
        foreach (var path in paths.OrderBy(x => x))
        {
            var node = new TreeNode { Name = path, Text = path };
            var arr = Regex.Matches(path, @"\d+.\d+")
                .Cast<Match>().Select(x => x.Value).ToArray();
    
            if (arr.Count() == 1)
                treeView1.Nodes.Add(node);
            else
            {
                var parentPath = string.Join(".", arr, 0, arr.Count() - 1);
                var parentNode = treeView1.Nodes.Find(parentPath, true).FirstOrDefault();
    
                if (parentNode != null)
                    parentNode.Nodes.Add(node);
            }
        }
    
        treeView1.EndUpdate();
    }
    
    private void TheCaller()
    {
        var revisionsList = //Get the list...
    
        PopulateTree(revisionsList);    
    }
    

    VB.NET

    Private Sub PopulateTree(paths As IEnumerable(Of String))
        TreeView1.BeginUpdate()
        TreeView1.Nodes.Clear()
    
        For Each path In paths.OrderBy(Function(x) x)
            Dim node As New TreeNode With {.Name = path, .Text = path}
            Dim arr = Regex.Matches(path, "\d+.\d+").
                Cast(Of Match).Select(Function(x) x.Value).ToArray()
    
            If arr.Count = 1 Then
                TreeView1.Nodes.Add(node)
            Else
                Dim parentPath = String.Join(".", arr, 0, arr.Count() - 1)
                Dim parentNode = TreeView1.Nodes.Find(parentPath, True).FirstOrDefault
    
                If parentNode IsNot Nothing Then
                    parentNode.Nodes.Add(node)
                End If
            End If
        Next
    
        TreeView1.EndUpdate()
    End Sub
    
    Private Sub TheCaller()
        Dim revisionsList = 'Get the list...
    
        PopulateTree(revisionsList)
    End Sub
    

    The result is:

    SOQ60904806