Search Wiki:

Show a ZIP within a TreeView in WinForms (VB)

TreeViewZip-VB.png

This app is a VB WinForms app that displays the contents of a ZIP file in a TreeView.

Below is the code for the just the Form. The most interesting methods for building the TreeView are AddTreeNode() and FindNodeForTag(). The approach is to enumerate (For Each) the entries in the zip file, and for each one, add a node to the treeview, and any required node hierarchy according to the path of the ZipEntry.

What is not shown is how to use the TreeView thus populated. One interesting possibility is to allow a right-click context menu popup, and extraction of a particular entry. This should be easy to achieve. The Tag property on each node defines the path of the ZipEntry, and this path can be used in the string indexer on the ZipFile instance. So in the onClick method for the context menu item, you can do zip(node.Tag).Extract().

To get a zip of the complete Visual Studio solution for this simple example, see here.

Imports Ionic.Zip
Imports System.Linq
Imports System.IO
 
Public Class Form1
 
    Private Sub Button1_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) Handles Button1.Click
        PopulateTreeView()
    End Sub
 
    Private zip As Ionic.Zip.ZipFile
 
    ''' <summary>
    ''' Populates TreeView1 with the entries in the zipfile, named by TextBox1
    ''' </summary>
    Private Sub PopulateTreeView()
        Try
            zip = ZipFile.Read(Me.TextBox1.Text)
 
            Me.TreeView1.Nodes.Clear()
            For Each e As ZipEntry In zip
                AddTreeNode(e.FileName)
            Next
 
        Catch ex As Exception
            '' eg, file does not exist, or access denied, etc
            MessageBox.Show("Exception: " + ex.ToString(), _
                            "Exception during zip processing", _
                            MessageBoxButtons.OK, _
                            MessageBoxIcon.Exclamation)
 
        Finally
            If Not (zip Is Nothing) Then
                zip.Dispose()
            End If
 
        End Try
    End Sub
 
    ''' <summary>
    ''' Add a node to the Treeview, for the given ZipEntry name
    ''' </summary>
    ''' <param name="name">name of the ZipEntry</param>
    ''' <returns>the TreeNode added</returns>
    ''' <remarks>
    ''' <para>
    ''' Entries in a zip file exist in a "flat container space": there is a single container, 
    ''' the zip file itself, that contains all entries. Even though each entry has a filename 
    ''' attached to it, and that filename may include a hierarchial directory path, the entry is 
    ''' always contained in the zipfile itself.  Even though it is possible to include directory 
    ''' entries in a zip file, those directory entries are not, themselves, containers - they do 
    ''' not contain other zip entries.  
    ''' </para>
    ''' <para>
    ''' This method overlays the zipentry, which exists only in a flat namespace, into a hierarchial 
    ''' tree, creating that tree from the pathname on the entry.  If the entry name is /a/b/c.txt,  
    ''' then this method adds 3 nodes to the TreeView, one for each segment in the path. 
    ''' </para>
    ''' <para>
    ''' The method is smart enough to find existing nodes matching subsegements of the path
    ''' for an entry. 
    ''' </para>
    ''' </remarks>
    Private Function AddTreeNode(ByVal name As String) As TreeNode
        If (name.EndsWith("/")) Then
            name = name.Substring(0, name.Length - 1)
        End If
        Dim node As TreeNode = FindNodeForTag(name, Me.TreeView1.Nodes)
        If Not (node Is Nothing) Then
            Return node
        End If
        Dim pnodeCollection As TreeNodeCollection
        Dim parent As String = Path.GetDirectoryName(name)
        If (parent = "") Then
            pnodeCollection = Me.TreeView1.Nodes
        Else
            pnodeCollection = AddTreeNode(parent.Replace("\", "/")).Nodes
        End If
        node = New TreeNode
        node.Text = Path.GetFileName(name)
        node.Tag = name ' full path
        pnodeCollection.Add(node)
        Return node
    End Function
 
    ''' <summary>
    ''' Returns the TreeNode for a given name 
    ''' </summary>
    ''' <param name="name">name of the ZipEntry</param>
    ''' <param name="nodes">The TreeNodeCollection to search</param>
    ''' <returns>the matching TreeNode, or nothing if none exists</returns>
    ''' <remarks>
    ''' This method is used by AddTreeNode() to find existing nodes.  
    ''' </remarks>
    Private Function FindNodeForTag(ByVal name As String, ByRef nodes As TreeNodeCollection) As TreeNode
        For Each node As TreeNode In nodes
            If (name = node.Tag) Then
                Return node
            ElseIf (name.StartsWith(node.Tag + "/")) Then
                Return FindNodeForTag(name, node.Nodes)
            End If
        Next
        Return Nothing
    End Function
 
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim openFileDialog1 As OpenFileDialog = New OpenFileDialog
 
        openFileDialog1.InitialDirectory = Me.TextBox1.Text
        openFileDialog1.Filter = "zip files|*.zip|EXE files|*.exe|All Files|*.*"
        openFileDialog1.FilterIndex = 1
        openFileDialog1.RestoreDirectory = True
 
        If (openFileDialog1.ShowDialog() = DialogResult.OK) Then
            Me.TextBox1.Text = openFileDialog1.FileName
            If (System.IO.File.Exists(Me.TextBox1.Text)) Then
                Button1_Click(sender, e)
            End If
        End If
 
    End Sub
End Class
 
Last edited Jul 7 at 5:16 PM  by Cheeso, version 5
Updating...
Page view tracker