Hierarchie in Treeview durch Binding funktioniert nicht

  • WPF

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von KingLM97.

    Hierarchie in Treeview durch Binding funktioniert nicht

    Hallo zusammen,

    ich versuche mich gerade an WPF und MVVM und habe mich dafür ein kleines Projekt gebastelt. Dort habe ich ein Treeview, welches ich gerne als eine Art Navigation verwenden möchte. Maximal zwei Ebenen sollen es werden.

    Allerdings wird bei mir nur die erste Ebene angezeigt und ich habe keine Möglichkeit diese auszuklappen.

    Hier der Code zu meinem Treeview:
    Spoiler anzeigen

    XML-Quellcode

    1. ​<TreeView Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding Path=Restaurants}">
    2. <TreeView.ItemTemplate>
    3. <HierarchicalDataTemplate DataType="{x:Type models:Restaurant}">
    4. <Label Content="{Binding Path=Name}" />
    5. <HierarchicalDataTemplate.ItemTemplate>
    6. <DataTemplate DataType="{x:Type models:Kategorie}">
    7. <Label Content="{Binding Path=Bezeichnung}" />
    8. </DataTemplate>
    9. </HierarchicalDataTemplate.ItemTemplate>
    10. </HierarchicalDataTemplate>
    11. </TreeView.ItemTemplate>
    12. </TreeView>


    Mein ViewModel sieht entsprechend so aus:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. ​Private _Restaurants As New ObservableCollection(Of Restaurant)
    2. Public Property Restaurants As ObservableCollection(Of Restaurant)
    3. Get
    4. Return _Restaurants
    5. End Get
    6. Set(value As ObservableCollection(Of Restaurant))
    7. _Restaurants = value
    8. End Set
    9. End Property
    10. Sub New()
    11. Restaurants = New ObservableCollection(Of Restaurant)
    12. Restaurants.Add(New Models.Restaurant With {.Name = "Test 1", .Kategorien = New ObservableCollection(Of Kategorie) From {New Kategorie With {.Bezeichnung = "Kat"}}})
    13. End Sub


    Und die beiden Models:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. ​Public Class Restaurant
    2. Inherits Modelbase
    3. Private _kategorien As New ObservableCollection(Of Kategorie)
    4. Private _ort As String
    5. Private _plz As Integer
    6. Private _straßeHausNr As String
    7. Private _beschreibung As String
    8. Private _name As String
    9. Private _iD As Integer
    10. Property ID As Integer
    11. Get
    12. Return _iD
    13. End Get
    14. Set(ByVal Value As Integer)
    15. If (_iD.Equals(Value)) Then Return
    16. _iD = Value
    17. NotifyPropertyChanged(NameOf(ID))
    18. End Set
    19. End Property
    20. Property Name As String
    21. Get
    22. Return _name
    23. End Get
    24. Set(ByVal Value As String)
    25. If (_name = Value) Then Return
    26. _name = Value
    27. NotifyPropertyChanged(NameOf(Name))
    28. End Set
    29. End Property
    30. Property Beschreibung As String
    31. Get
    32. Return _beschreibung
    33. End Get
    34. Set(ByVal Value As String)
    35. If (_beschreibung = Value) Then Return
    36. _beschreibung = Value
    37. NotifyPropertyChanged(NameOf(Beschreibung))
    38. End Set
    39. End Property
    40. Property StraßeHausNr As String
    41. Get
    42. Return _straßeHausNr
    43. End Get
    44. Set(ByVal Value As String)
    45. If (_straßeHausNr = Value) Then Return
    46. _straßeHausNr = Value
    47. NotifyPropertyChanged(NameOf(StraßeHausNr))
    48. End Set
    49. End Property
    50. Property Plz As Integer
    51. Get
    52. Return _plz
    53. End Get
    54. Set(ByVal Value As Integer)
    55. If (_plz.Equals(Value)) Then Return
    56. _plz = Value
    57. NotifyPropertyChanged(NameOf(Plz))
    58. End Set
    59. End Property
    60. Property Ort As String
    61. Get
    62. Return _ort
    63. End Get
    64. Set(ByVal Value As String)
    65. If (_ort = Value) Then Return
    66. _ort = Value
    67. NotifyPropertyChanged(NameOf(Ort))
    68. End Set
    69. End Property
    70. Property Kategorien As ObservableCollection(Of Kategorie)
    71. Get
    72. Return _kategorien
    73. End Get
    74. Set(value As ObservableCollection(Of Kategorie))
    75. If (_kategorien.Equals(value)) Then Return
    76. _kategorien = value
    77. NotifyPropertyChanged(NameOf(Kategorien))
    78. End Set
    79. End Property
    80. Public Overrides Function ToString() As String
    81. Return Me.Name
    82. End Function
    83. End Class


    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Kategorie
    2. Inherits Modelbase
    3. Private _speisen As ObservableCollection(Of Speise)
    4. Private _beschreibung As String
    5. Private _bezeichnung As String
    6. Private _iD As Integer
    7. Property ID As Integer
    8. Get
    9. Return _iD
    10. End Get
    11. Set(ByVal Value As Integer)
    12. If (_iD.Equals(Value)) Then Return
    13. _iD = Value
    14. NotifyPropertyChanged(NameOf(ID))
    15. End Set
    16. End Property
    17. Property Bezeichnung As String
    18. Get
    19. Return _bezeichnung
    20. End Get
    21. Set(ByVal Value As String)
    22. If (_bezeichnung = Value) Then Return
    23. _bezeichnung = Value
    24. NotifyPropertyChanged(NameOf(Bezeichnung))
    25. End Set
    26. End Property
    27. Property Beschreibung As String
    28. Get
    29. Return _beschreibung
    30. End Get
    31. Set(ByVal Value As String)
    32. If (_beschreibung = Value) Then Return
    33. _beschreibung = Value
    34. NotifyPropertyChanged(NameOf(Beschreibung))
    35. End Set
    36. End Property
    37. Property Speisen As ObservableCollection(Of Speise)
    38. Get
    39. Return _speisen
    40. End Get
    41. Set(value As ObservableCollection(Of Speise))
    42. If (_speisen.Equals(value)) Then Return
    43. _speisen = value
    44. NotifyPropertyChanged(NameOf(Speisen))
    45. End Set
    46. End Property
    47. Public Overrides Function ToString() As String
    48. Return Me.Bezeichnung
    49. End Function
    50. End Class​


    Habe natürlich auch schon Google bemüht und habe das sowie dies gefunden. Ich denke, dass ich es genauso habe, nur mit dem Unterschied, dass ich zwei Ebenen möchte und keine drei. Bin über jede Hilfe dankbar!

    Vielen Dank :)
    Hallo @KingLM97

    Kennst du schon mein Tutorial?

    In Kapitel 2.1.1.2 gehe ich auch auf HirachicalDataTemplates ein und habe ein Projekt angehängt wo ich an Klassen binde.
    Vieleicht hilft dir das ja schon weiter. Ansonsten gebe mir bitte bescheid, dann schau ich mir das mal genauer an.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    @Nofear23m

    Ja, ich kenne das Tutorial, schaue da immer mal rein wenn ich was brauche, nur bei den Templates wohl nicht dran gedacht.

    Habe es jetzt in die Resources gepackt, wie bei dir Beschrieben:

    XML-Quellcode

    1. ​<TreeView Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding Path=Restaurants}">
    2. <TreeView.Resources>
    3. <HierarchicalDataTemplate DataType="{x:Type models:Restaurant}">
    4. <Label Content="{Binding Path=Name}" />
    5. </HierarchicalDataTemplate>
    6. <HierarchicalDataTemplate DataType="{x:Type models:Kategorie}">
    7. <Label Content="{Binding Path=Bezeichnung}" />
    8. </HierarchicalDataTemplate>
    9. </TreeView.Resources>
    10. </TreeView>


    Aber da passiert immer noch nichts mit einer zweiten Ebene :(
    Hallo

    Das sieht schon mal gut aus. Du hast nun Templates für gewisse Datentypen definiert. Die WPF weis nun also "OK, wenn ich den Datentyp "Restaurant" bekommen dann rendere ich diesen mit einem Label. Gut, aber welche Eigenschaft enthält die Auflistung? Das musst du der WPF noch sagen.

    XML-Quellcode

    1. <TreeView Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding Path=Restaurants}">
    2. <TreeView.Resources>
    3. <HierarchicalDataTemplate ItemsSource="{Binding Kategorien}" DataType="{x:Type models:Restaurant}">
    4. <Label Content="{Binding Path=Name}" />
    5. </HierarchicalDataTemplate>
    6. <HierarchicalDataTemplate ItemsSource="{Binding Speisen}" DataType="{x:Type models:Kategorie}">
    7. <Label Content="{Binding Path=Bezeichnung}" />
    8. </HierarchicalDataTemplate>
    9. <HierarchicalDataTemplate DataType="{x:Type models:Speise}">
    10. <StackPanel Orientation="Horizontal">
    11. <TextBlock Text="{Binding Bezeichnung}"/>
    12. </StackPanel>
    13. </HierarchicalDataTemplate>
    14. </TreeView.Resources>
    15. </TreeView>


    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##