Search code examples
c#wpfvb.nettreeview

WPF TreeView folderbrowser - data binding


I want to show in a WPF TreeView a hierarchical folderbrowser based on on this class:

Public Class _Folder
     Public Property Name As String
     Public ReadOnly Property SubFolders As List(Of _Folder) = New List(Of _Folder)()
End Class

Loading my Window I create my demodata:

Private Sub Test2_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded

        Dim lst As New List(Of _Folder)

        Dim str As _Folder = New _Folder()

        str.Name = "Client 1"
        For x = 1 To 10
            Dim y As _Folder = New _Folder With {.Name = "Mandant " & x}
            str.SubFolders.Add(y)
        Next
        lst.Add(str)

        str = New _Folder()
        str.Name = "Client 2"
        For x = 1 To 10
            Dim y As _Folder = New _Folder With {.Name = "Mandant " & x}
            str.SubFolders.Add(y)
        Next
        lst.Add(str)

        tvw.DataContext = lst

    End Sub

In XAML I have the following TreeView

<TreeView x:Name="tvw" ItemsSource="{Binding}" HorizontalAlignment="Left" Height="798" Margin="10,50,0,0" VerticalAlignment="Top" Width="600">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate DataType="{x:Type TreeViewItem}" ItemsSource="{Binding}">
                    <TextBlock Text="{Binding Name}"/>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>

But result is just like this, so no

enter image description here

Can oneone help me with that?

EDIT: Changed XAML to

<TreeView x:Name="tvw" ItemsSource="{Binding}" HorizontalAlignment="Left" Height="798" Margin="10,50,0,0" VerticalAlignment="Top" Width="600">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate DataType="{x:Type local:_Folder}" ItemsSource="{Binding Path=Name}">
                    <TextBlock Text="{Binding Path=Name}"/>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>

Now the result shows that there exists subfolders, but the subfolder names are not show:

enter image description here


Solution

  • This is how I solved it finally:

    The class:

    Public Class _Folder
        Public Property Name As String
        Public Property FullPath As String
        Public ReadOnly Property SubFolders As List(Of _Folder) = New List(Of _Folder)()
    End Class
    

    The XAML:

    <TreeView x:Name="tvw" ItemsSource="{Binding}" HorizontalAlignment="Left" Height="798" Margin="10,50,0,0" VerticalAlignment="Top" Width="600">
        <TreeView.ItemContainerStyle>
            <Style>
                <Setter Property="TreeViewItem.IsExpanded" Value="True"/>
            </Style>
        </TreeView.ItemContainerStyle>
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate  DataType="{x:Type local:_Folder}" ItemsSource="{Binding Path=SubFolders}">
                <TextBlock Text="{Binding Path=Name}" ToolTip="{Binding Path=FullPath}"/>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
    

    The code:

    Dim lstFolders As New List(Of _Folder)
    Dim RootFolder As New _Folder
    
    For Each f In _items
        If f.Contains("\\") Then f = f.Replace("\\", ":")
        Dim drive = f.Split(":")(0)
        Dim path = f.Split(":")(1)
    
        'If String.IsNullOrEmpty(drive) Then Continue For
        RootFolder.Name = drive
    
        Dim charSeparators As Char() = New Char() {System.IO.Path.DirectorySeparatorChar}
        Dim pathSplit() As String = path.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries)
    
        Dim currentFolder As _Folder = RootFolder
        For Each level In pathSplit
            If String.IsNullOrEmpty(level) Then Continue For
            Dim foundFolder = (From x In currentFolder.SubFolders Where x.Name = level Select x).FirstOrDefault
            If foundFolder Is Nothing Then
                foundFolder = New _Folder
                foundFolder.Name = level
                If f.StartsWith(":") Then 'Netzwerkpfad
                    foundFolder.FullPath = (f.Substring(0, f.IndexOf(level)) & level).Replace(":", "\\")
                Else 'Pfad mit Laufwerksbuchstaben
                    foundFolder.FullPath = f.Substring(0, f.IndexOf(level)) & level
                End If
                currentFolder.SubFolders.Add(foundFolder)
            End If
            currentFolder = foundFolder
        Next
    
    Next
    
    lstFolders.Add(RootFolder)
    
    tvw.DataContext = lstFolders
    

    My list(of String) looks like this, it is just a bunch of folders:

    c:\temp\freigabe
    c:\temp\ftptest
    c:\temp\ftptest\testen
    c:\temp\in
    c:\temp\in - Kopie
    c:\temp\in - Kopie\1
    c:\temp\in - Kopie\1\yyy
    c:\temp\in - Kopie\1\yyy\yyyyy
    c:\temp\in - Kopie\2
    c:\temp\in2
    c:\temp\ipadb
    c:\temp\out
    c:\temp\out2
    c:\temp\Processes2
    c:\temp\Processes2\Kassenbelege
    c:\temp\Processes2\Kassenbelege\images
    c:\temp\Processes2\Posteingang
    c:\temp\Processes2\Posteingang\images
    c:\temp\Processes2\Rechnungen
    c:\temp\Processes2\Rechnungen\images
    c:\temp\Processes2\Rechnungen\images\backup
    c:\temp\test