LuckyLuke82 LuckyLuke82 - 3 days ago 6
Vb.net Question

Listview Explorer - navigate directory buttons like Windows Explorer?

I'm creating custom Explorer using Listview, and I need to include navigate buttons for listing directories, such as in Windows Explorer. So, in short explanation I need It to work like this:


  1. When you double-click "folder" in Listview, you go level down inside that directory (I got this working)

  2. When you do this, button for navigating backwards should become active and you can return to previous directory position. If returned, then also button for going upwards should be active - to go back into directory where you were when double-clicked on "folder".

  3. I want this to be working for as many up/down folder paths as user clicks - this is how Windows Explorer works.



I tried by declaring public variable for paths (which are stored by ListviewItem tags), but you can move up/down into directories only once. I want It to work as many times as User can navigate, If there are folders inside directories, ofcourse.

This is my latest try (with List of strings):

Dim Navigation as List(of String)

Private Sub ListView1_DoubleClick(sender As Object, e As EventArgs) Handles ListView1.DoubleClick

If ListView1.SelectedItems(0).ImageKey = "folder" Then

Dim ItemDirectory As IO.DirectoryInfo
ItemDirectory = New IO.DirectoryInfo(ListView1.SelectedItems(0).Tag.ToString)
'Pass this path to List of strings too
Navigation = ItemDirectory

'... I'm adding each subdirectories and files in Listview here
Else '... If not folder then just open file by double-clicking
Process.Start(ListView1.SelectedItems(0).Tag)
End If
BtnNavigateBackwards.Enabled=True 'Enable navigating backwards
End Sub

Private Sub BtnNavigateForward_Click(sender As Object, e As EventArgs) Handles BtnNavigateForward.Click

If Navigation.Count <> 0 Then

'Get directory that is one level down from where you are in Listview - I was allready in It by clicking on "folder" item
Dim ItemDirectory As IO.DirectoryInfo
ItemDirectory = New IO.DirectoryInfo(Navigation. ???? go to path 1 level down each click until last list of string ???)
'... Adding each subdirectories and files for directory one level down
'... Also checking for "folder" item in directory - If they are not then disable this button
End If

End Sub

Private Sub BtnNavigateBackwards_Click(sender As Object, e As EventArgs) Handles BtnNavigateBackwards.Click
'Get directory one level up from where I am in Listview
Dim ItemDirectory As IO.DirectoryInfo
ItemDirectory = New IO.DirectoryInfo(IO.Path.GetDirectoryName(Navigation. ?????? how to go only 1 level up each click ???))

'... Adding each subdirectory and files to Listview

End Sub


This is not my complete code as It's very long, and I know there are many things missing. But most important question is - can I even navigate up/down with List of strings like that ?

Answer

Problem solved. You can navigate like in Explorer by doing some loops of item tags. But first we have to store item tags in a List of strings. So, in my case I stored "folder" item tags when I double click on them, to go one directory down:

 Private Navigation As New List(Of String) 'We store each item tag in here and use It for navigating in Listview directories
'Handle double click on folders - when clicked you go into folder, as in Explorer
Private Sub ListView1_DoubleClick(sender As Object, e As EventArgs) Handles ListView1.DoubleClick
        If sender Is Nothing OrElse Not TypeOf sender Is System.Windows.Forms.ListView Then Exit Sub
        With CType(sender, System.Windows.Forms.ListView)
            If sender.SelectedItems(0).ImageKey = "folder" Then
                'Get directory of folder
                Dim ItemDirectory As IO.DirectoryInfo
                ItemDirectory = New IO.DirectoryInfo(sender.SelectedItems(0).Tag.ToString)
                'Then we also add folder item to our variable
                Navigation.Add(sender.SelectedItems(0).Tag.ToString)
                sender.Items.Clear()
                'Then we add each subdirectories and files using GetDirectories  and GetFiles 
...
...
...

End Sub
Private Sub Btn_NavigateForward_Click(sender As Object, e As EventArgs) Handles Btn_NavigateForward.Click
        Dim i As Integer = 0
        'When we navigate forward Listview has items, so we need to loop their tags. If loop finds same string that we stored in  Navigation variable than this means we were allready in this directory
        For i = ListView1.Items.Count - 1 To 0 Step -1
            For Each path As String In Navigation
                If ListView1.Items(i).Tag.ToString = path Then
                    Navigation_Forward(ListView1, path)
                    Exit Sub
                End If
            Next
        Next
End Sub

 Private Sub Btn_NavigateBack_Click(sender As Object, e As EventArgs) Handles Btn_NavigateBack.Click
'When navigating back we have two options – either no items in a directory or there are some !
'In both cases we just do correct loops. For no folder we loop backwards in Navigation variable strings
        If ListView1.Items.Count = 0 Then
            For j As Integer = Navigation.Count - 1 To 0 Step -1
                Dim s As String = Navigation.Item(j)
                Navigation_Back(ListView1, s)
                Exit Sub
            Next j
'If items are in Listview then we first do a loop through items, and a backward loop in Navigation variable – looking for a »folder« tag match
        ElseIf ListView1.Items.Count > 0 Then
            Dim i As Integer = 0
            For i = 0 To ListView1.Items.Count - 1
                For j As Integer = Navigation.Count - 1 To 0 Step -1
                    Dim s As String = Navigation.Item(j)
                    If s = IO.Path.GetDirectoryName(ListView1.Items(i).Tag.ToString) Then
                        Navigation_Back(ListView1, s)
                        Exit Sub
                    End If
                Next
            Next
'And here is sub for navigating forward – I'm posting only this one, because Navigation_Back is basically same, you just have to define Directory_item like this: »Directory_Item = New IO.DirectoryInfo(IO.Path.GetDirectoryName(path))« - instead of what you see in this sub here
    Public Sub Navigation_Forward(ByVal sender As Object, ByVal Path As String)

        Dim LView As System.Windows.Forms.ListView = sender

        With CType(sender, System.Windows.Forms.ListView)

            Dim Directory_Item = New IO.DirectoryInfo(Path)

            LView.Items.Clear()

            For Each My_directory As IO.DirectoryInfo In Directory_Item.GetDirectories

                Dim Lvi As New ListViewItem

                Lvi.Tag = My_directory.FullName
                Lvi.ImageKey = CacheShellIcon(My_Directory.FullName)
                Lvi.Text = My_Directory.Name
                Lvi.Items.Add(Directory_Item)

            Next

            'Do same loop for files if desired
        End With

     End Sub

Code works for buttons regarding navigating Listview contents only. However I think It can be adapted to work with Treeview nodes too if desired.

Comments