TreeView Kategorien aus DB anzeigen

  • WPF

Es gibt 24 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    TreeView Kategorien aus DB anzeigen

    Hallo

    Ich habe eine Frage, Ich speichere die Kategorien in einer Datenbank. Die Datenbank ist so aufgebaut (ID | Kat_Nummer | Kat_Hauptnummer | Kat_Name)

    ist die Kat_Hauptnummer leer so ist diese eine Hauptkategorie, ist in Kat_Hauptnummer die Nummer wo es untergeordnet sein soll, so Steht da die Kat_Nummer drin.

    z.b.

    ID | Kat_Nummer | Kat_Hauptnummer | Kat_Name
    1 | 1001 | | Hauptkategorie
    2 | 1002 | 1001 | Unterknoten
    3 | 1003 | | Hauptkategorie 2
    4 | 1004 | 1003 | Unterknoten
    5 | 1005 | 1004 | Unter Unterknoten
    6 | 1006 | 1001 | Unter Unterknoten

    Ich hoffe man kann meine DB für die Kategorien verstehen wie ich es gemacht habe.
    Nun möchte ich diese in TreeView anzeigen lassen.

    Mein WPF Code ist so

    Quellcode

    1. <TreeView x:Name="TreeView1" >
    2. </TreeView>


    und mein VB.Net Code sieht so aus

    VB.NET-Quellcode

    1. For S = 0 To DataSet1.Kategorie.Rows.Count - 1
    2. If DataSet1.Kategorie.Rows(S).Item(2).ToString = "" Then
    3. Dim newNode As New TreeViewItem
    4. newNode.Header = DataSet1.Kategorie.Rows(S).Item(3).ToString
    5. For US = 0 To DataSet1.Kategorie.Rows.Count - 1
    6. If DataSet1.Kategorie.Rows(US).Item(2).ToString = DataSet1.Kategorie.Rows(S).Item(1).ToString Then
    7. newNode.Items.Add(DataSet1.Kategorie.Rows(US).Item(3).ToString)
    8. End If
    9. Next
    10. TreeView1.Items.Add(newNode)
    11. End If
    12. Next


    Die Kategorie wird vorher in ein Dataset geladen und will es aus der Dataset wieder abrufen.
    Nur leider funktioniert mein Code nur für 1 Unterknoten, wie kann man es machen damit beliebig viele Unterknoten abrufen kann.

    Wäre es auch möglich das nicht nur der Kat_Name als Anzeige eingefügt wird sondern auch die Kat_Nummer

    Was und wie muss ich das ändern?
    Danke schon mal im voraus.
    Hallo

    Ich kenne dein Dataset nicht und die meisten arbeiten unter WPF weniger mit Datasets da man normalerweise mit einer MVVM oder einer MVVM ähnlichen Struktur unter WPF arbeitet und hier dann ohnehin mit Klassen arbeitet aber wenn dein DataSet in Ordnung ist sollte es reichen ein Template zu definieren.

    Ich kann dir hier meine Tutorialreihe ans Herz legen. Im Kapitel 2.1.1.2 - Templates habe ich sogar explizit ein Beispiel mdit einem Treeview mit drinnen. Zwar anhand einer Klassen-Struktur, aber das ist ja im Grunde egal da du ja auf jedes Objekt binden kannst.

    Probiers mal aus.

    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. ##

    nach meine Erfahrung ist Dataset und Wpf ziemlich ungünstig, weil die bindablen Properties eines Datasets im Xaml nicht erkannt werden.
    Da muss man also die Bindings setzen im Vertrauen, dass sie richtig sind, und richtig geschrieben - und die vom Xaml-Designer angebotenen Bindings kann man nicht verwenden.
    Wie würdet Ihr das losen?
    Ich habe die Daten in ein SQLite DB die ich dann in Dataset lade
    Es sind ganz viele Tabellen die in verschiedene SQLite DB gespeichert sind.
    das Tolle an Dataset ist für mich das ich 1. ein Designer habe und die Tabellen mit einander verbinden kann.

    Ich wäre für jeden Tipp Dankbar.

    Das mit TreeView hätte ich irgendwie so gerne

    Quellcode

    1. If Hauptkategorienummer = "" then
    2. nodes.add(Kat_Name, Kategorienummer)
    3. else
    4. nodes.add(kat_Name, Kategorienummer) in (Hauptkategorienummer)
    5. end if


    die das auch unter knoten auch bei andern unter knoten geht. Ich hoffe ihr versteht was ich meine

    dema schrieb:

    Ich hoffe ihr versteht was ich meine
    Jo, eine Baumstruktur aus einer DataTable aufbauen habich inne letzten 3 Wochen zweimal gemacht, in sehr unterschielichen Kontexten (mal ein TV aufgebaut, mal ein Menü).

    Nur in Wpf geht man da ganz anders vor, da fasst man den Treeview oder das Menü codeseitig überhaupt nicht an.
    Sondern man codet ein geeignetes Viewmodel - also in diesem Fall eine Baumstruktur, und daran bindet man dann zB einen Xaml-Treeview (oder halt ein Xaml-Menü - was wolle).

    Also da sehe ich jetzt bei dir mehrere Probleme:
    • scheinbar kennst du das mittm Viewmodel garnet - da hats nicht viel Sinn, iwas zu beraten oder gar hin-zucoden, was du nirgends einbauen kannst, weil deine Anwendungs-Struktur garnichts dafür bereitstellt.
    • Dataset ist numa schlecht geeignet für Wpf-Bindings. Also es geeeeht, prinzipiell, aber es ist ein Gekrepel, an das man als Anfänger nicht gewöhnt werden sollte.

    Was anneres: Wieso sind deine Daten in mehrere Sqlite-Dateien verstreut, und du sammelst es dann im Dataset zusammen?
    Warum hast du nicht eine SqLite-Datenbank mit alle Tabellen drinne?
    Warum benötigst du überhaupt eine oder mehrere SqLite-Datenbank(en)? ein Dataset braucht keine SQLite-DB (oder eine andere DB), um sich auf Platte zu speichern.
    Ich habe mir ein zur Übung ein Programm gesucht und in diesen sind mehre Access DB und ich arbeite lieber mit SQLite
    Wie viele DB es sind spielte ja eigentlich keine rolle

    Ich habe mir einiges durchgelesen und nun glaube ich das ich den Richtigen WPF code habe

    Quellcode

    1. <TreeView Name="trv_Kategorie">
    2. <TreeView.ItemTemplate>
    3. <HierarchicalDataTemplate ItemsSource="{Binding Kategorie}">
    4. <StackPanel Orientation="Horizontal">
    5. <TextBlock Text="{Binding KategorieName}" Margin="0,0,4,0" />
    6. </StackPanel>
    7. </HierarchicalDataTemplate>
    8. </TreeView.ItemTemplate>
    9. </TreeView>


    in VB.Net

    VB.NET-Quellcode

    1. Public Sub New()
    2. InitializeComponent()
    3. Dim Kategorie As List(Of KategorieKlasse) = New List(Of KategorieKlasse)()
    4. For S = 0 To DataSet1.Kategorie.Rows.Count - 1
    5. If DataSet1.Kategorie.Rows(S).Item(2).ToString = "" Then
    6. Dim Kategorie1 As KategorieKlasse = New KategorieKlasse() With {
    7. .KategorieNummer = DataSet1.Kategorie.Rows(S).Item(1).ToString,
    8. .KategorieName = DataSet1.Kategorie.Rows(S).Item(3).ToString
    9. }
    10. Else
    11. End If
    12. Next
    13. End Sub
    14. Public Class KategorieKlasse
    15. Public Sub New()
    16. Me.Kategorie = New ObservableCollection(Of KategorieKlasse)()
    17. End Sub
    18. Public Property KategorieNummer As String
    19. Public Property HauptKategorieNummer As String
    20. Public Property KategorieName As String
    21. Public Property Kategorie As ObservableCollection(Of KategorieKlasse)
    22. End Class

    aber das funktioniert so auch nicht
    Danke das me.DataContext funktioniert leider nicht aber ich hab es gefunden mit trv_Kategorie.ItemsSource = Kategorie

    aber leider wird mir hier die Unterkategorie nicht mit angezeigt, ich habe nun mal die DB raus gelassen und dafür eine Schleife rein

    Hier mein Code bis jetzt

    WPF:

    Quellcode

    1. <TreeView Name="trv_Kategorie">
    2. <TreeView.ItemTemplate>
    3. <HierarchicalDataTemplate ItemsSource="{Binding Kategorie}">
    4. <StackPanel Orientation="Horizontal">
    5. <TextBlock Text="{Binding KategorieNummer}" Margin="0,0,4,0" />
    6. <TextBlock Text="{Binding KategorieName}" Margin="0,0,4,0" />
    7. </StackPanel>
    8. </HierarchicalDataTemplate>
    9. </TreeView.ItemTemplate>
    10. </TreeView>

    VB.Net:

    VB.NET-Quellcode

    1. Public Sub New()
    2. InitializeComponent()
    3. Dim Kategorie As List(Of KategorieKlasse) = New List(Of KategorieKlasse)()
    4. For S = 0 To 10
    5. Dim Kategorie1 As KategorieKlasse = New KategorieKlasse() With {
    6. .KategorieName = "Root" & S,
    7. .KategorieNummer = "Nummer_" & S
    8. }
    9. If Kategorie1.KategorieNummer = "Nummer_3" Then
    10. S = S + 1
    11. Kategorie1.UnterKategorie.Add(New KategorieKlasse() With {
    12. .KategorieName = "UnterName_" & S,
    13. .KategorieNummer = "UnterNummer_" & S
    14. })
    15. End If
    16. Kategorie.Add(Kategorie1)
    17. Next
    18. trv_Kategorie.ItemsSource = Kategorie
    19. End Sub
    20. Public Class KategorieKlasse
    21. Public Sub New()
    22. Me.UnterKategorie = New ObservableCollection(Of KategorieKlasse)()
    23. End Sub
    24. Public Property KategorieNummer As String
    25. Public Property KategorieName As String
    26. Public Property UnterKategorie As ObservableCollection(Of KategorieKlasse)
    27. End Class

    ich möchte das er mir in ein bestimmten KategorieNummer den unterknoten macht, aber irgendwie funktioniert das nicht so

    Ich hab das Beispiel von dieser Seite genommen wpf-tutorial.com/de/86/das-tre…uswahl-expansionszustand/

    XML-Quellcode

    1. <TreeView Name="trv_Kategorie">
    2. <TreeView.ItemTemplate>
    3. <HierarchicalDataTemplate ItemsSource="{Binding UnterKategorie}">
    4. <StackPanel Orientation="Horizontal">
    5. <TextBlock Text="{Binding KategorieNummer}" Margin="0,0,4,0" />
    6. <TextBlock Text="{Binding KategorieName}" Margin="0,0,4,0" />
    7. </StackPanel>
    8. </HierarchicalDataTemplate>
    9. </TreeView.ItemTemplate>
    10. </TreeView>

    Kannst dir auch dieses Tut antun - da wird ein Tree aus dem Dateisystem aufgebaut.
    Wird auch erklärt das mittm HierarchicalTemplate.
    Ausserdem ist dort der MVVM-Pattern implementiert.
    Hallo

    Danke Ich schau mir diese Tutorials an.

    Ich habe nun ein Problem mit dem Unter Unterknoten
    Jetzt habe ich so das ich ein Hauptknoten habe und 1 Unterknoten aber das es bei bestimmten Unterknoten nochmal ein Unterknoten hinzufügt geht es leider nicht.

    Ich will das so. Jeder Knoten hat eine Nummer und ich möchte das es bei Bestimmte Knoten Nummer ein unterknoten hinzugefügt wird.
    -Hauptknoten
    --unterKnoten
    ---Unter UnterKnoten
    -----Unter Unter Unter Knoten

    Ich hab es mal so Probiert aber ergibt leider nicht mein Ergebnis

    VB.NET-Quellcode

    1. Public Sub New()
    2. InitializeComponent()
    3. Dim Kategorie As List(Of KategorieKlasse) = New List(Of KategorieKlasse)()
    4. For S = 0 To 10
    5. Dim Kategorie1 As KategorieKlasse = New KategorieKlasse() With {
    6. .KategorieName = "Root" & S,
    7. .KategorieNummer = "Nummer_" & S
    8. }
    9. If Kategorie1.KategorieNummer = "Nummer_3" Then
    10. S = S + 1
    11. Kategorie1.UnterKategorie.Add(New KategorieKlasse() With {
    12. .KategorieName = "UnterName_" & S,
    13. .KategorieNummer = "UnterNummer_" & S
    14. })
    15. End If
    16. Kategorie.Add(Kategorie1)
    17. Next
    18. For UK = 0 To Kategorie.Count - 1
    19. For UKS = 0 To Kategorie.Item(UK).UnterKategorie.Count - 1
    20. If Kategorie.Item(UK).UnterKategorie.Item(UKS).KategorieNummer.ToString = "UnterNummer_4" Then
    21. Kategorie.Item(UK).UnterKategorie.Add(New KategorieKlasse() With {
    22. .KategorieName = "UnterName_12",
    23. .KategorieNummer = "UnterNummer_12"})
    24. End If
    25. Next
    26. Next
    27. trv_Kategorie.ItemsSource = Kategorie
    28. End Sub
    29. Public Class KategorieKlasse
    30. Public Sub New()
    31. Me.UnterKategorie = New ObservableCollection(Of KategorieKlasse)()
    32. End Sub
    33. Public Property KategorieNummer As String
    34. Public Property KategorieName As String
    35. Public Property UnterKategorie As ObservableCollection(Of KategorieKlasse)
    36. End Class

    Hoffe Ihr habt eine Lösung für mich
    Eine Lösung könnemer dir net geben, weil wir haben deine Daten nicht.
    Woher sollemer denn wissen, welcher knoten in welchem anneren als Unterknoten landen soll?

    Dafür muss man ja iwie Daten einlesen, wo das iwie definiert ist, und daraus dann die Baumstruktur aufbauen.
    In meim bereits gegebenem Wpf-Sample wird die File-System-Datenstruktur ausgelesen - das ist etwas speziell, weil die ist bereits baumartig.

    Hier wird eine Datenbank-Tabelle ausgelesen: Menü aus Datenbank
    Dassis auch speziell, und v.a. völlig oversized.

    Hier wird eine DataTable ausgelesen: Erweiterter Umgang mit typisiertem DataSet -> Tabellennamen lesen/Namensübergabe etc.
    Aber nur am Anfang des Threads - dann verliert sich das in die Besprechung von allem wasses so gibt.

    Beide Samples sind aber auch kein Wpf.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Ich hab das jetzt mal mit ein SQLite Datenbank gemacht das man es sieht wie ich mir das vorstelle
    Im Bild sieht man den Aufbau der Tabelle mit dem Inhalt.
    Genau diese will ich in TreeView anzeigen mit die Unterknoten

    Anbei mein Code

    WPF:

    Quellcode

    1. <Window x:Class="MainWindow"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    6. xmlns:local="clr-namespace:MvvM_Treeview"
    7. mc:Ignorable="d"
    8. Title="MainWindow" Height="450" Width="488.952">
    9. <Grid>
    10. <TreeView Name="trv_Kategorie">
    11. <TreeView.ItemTemplate>
    12. <HierarchicalDataTemplate ItemsSource="{Binding UnterKategorie}">
    13. <StackPanel Orientation="Horizontal">
    14. <TextBlock Text="{Binding KategorieNummer}" Margin="0,0,4,0" />
    15. <TextBlock Text="{Binding KategorieName}" Margin="0,0,4,0" />
    16. </StackPanel>
    17. </HierarchicalDataTemplate>
    18. </TreeView.ItemTemplate>
    19. </TreeView>
    20. </Grid>
    21. </Window>


    VB.Net

    VB.NET-Quellcode

    1. Imports System.Collections.ObjectModel
    2. Class MainWindow
    3. Public Sub New()
    4. InitializeComponent()
    5. Dim Kategorie As List(Of KategorieKlasse) = New List(Of KategorieKlasse)()
    6. Dim DB_Verbindung As New System.Data.SQLite.SQLiteConnection
    7. Dim db_Befehl As System.Data.SQLite.SQLiteCommand
    8. DB_Verbindung.ConnectionString = "Data Source = kategorie.sdb"
    9. DB_Verbindung.Open()
    10. db_Befehl = DB_Verbindung.CreateCommand
    11. db_Befehl.CommandText = "SELECT Kat_Nummer, Kat_Hauptnummer, Kat_Name FROM Kategorie"
    12. Dim SQLreader As System.Data.SQLite.SQLiteDataReader = db_Befehl.ExecuteReader()
    13. While SQLreader.Read()
    14. If SQLreader(1) = "" Then
    15. Dim Kategorie1 As KategorieKlasse = New KategorieKlasse() With {
    16. .KategorieName = SQLreader(2),
    17. .KategorieNummer = SQLreader(0)
    18. }
    19. Kategorie.Add(Kategorie1)
    20. Else
    21. Dim Kategorie2 As KategorieKlasse = New KategorieKlasse() With {
    22. .KategorieName = SQLreader(2),
    23. .KategorieNummer = SQLreader(0)
    24. }
    25. Kategorie.Add(Kategorie2)
    26. End If
    27. End While
    28. trv_Kategorie.ItemsSource = Kategorie
    29. End Sub
    30. Public Class KategorieKlasse
    31. Public Sub New()
    32. Me.UnterKategorie = New ObservableCollection(Of KategorieKlasse)()
    33. End Sub
    34. Public Property KategorieNummer As String
    35. Public Property KategorieName As String
    36. Public Property UnterKategorie As ObservableCollection(Of KategorieKlasse)
    37. End Class
    38. End Class


    Mehr Code ist noch nicht vorhanden da ich ja jedes eigene Element erst lernen will.

    Ich bekomm es nicht hin und ich finde nirgendwo was wie man ein unterknoten zu einen bestimmten knoten hinzufügen kann.
    das MVVM habe ich nun auch Installiert
    Bilder
    • SQL_Treeview.JPG

      56,21 kB, 648×381, 12 mal angesehen

    dema schrieb:

    ... da ich ja ... erst lernen will.
    dieses als erstes: Visual Studio - Empfohlene Einstellungen
    Deinem Code sehe ich an, dass du im Grunde noch garnet vb.net programmierst, sondern im Grunde einen Halb-OOP-VB6-VB.Net-Hybrid-Dialekt.
    Damit sofort aufhören, und so nicht weitermachen.
    Die Empfehlungen des Tuts umsetzen, und die sich dann zeigenden Fehler korrigieren.
    Dabei kann ich auch helfen, und nu überleg ich mir derweil die Methode, wie mans mit deine Kategorien baummässig hinbekommt....

    Dein Einlesen musste auch soweit korrigieren, dasses funzt. In deine DB gibts 4 Properties, in deiner Kategorie-Klasse aber nur drei - und einlesen tuste nur zwei.
    Schreib ein Einlesen, was einfach eine flache Liste von kategorien erstellt.
    Am besten eine Methode, der du die Connection übergibst, und die eine ObservableCollection(Of Kategorie) returnt.
    Aber wie gesagt: als erstes die Einstellungen.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Hallo
    Ich habe die Einstellungen geändert und festgestellt das die String nicht mehr einfach mit = String ist sondern mit =CType("text", String)

    nun hat sich mein Code so geändert

    VB.Net:

    VB.NET-Quellcode

    1. Imports System.Collections.ObjectModel
    2. Class MainWindow
    3. Private Sub DBerstellen()
    4. Dim DB_Verbindung As New System.Data.SQLite.SQLiteConnection
    5. Dim db_Befehl As System.Data.SQLite.SQLiteCommand
    6. DB_Verbindung.ConnectionString = "Data Source = kategorie.sdb"
    7. DB_Verbindung.Open()
    8. db_Befehl = DB_Verbindung.CreateCommand
    9. db_Befehl.CommandText = "CREATE TABLE Kategorie (ID INTEGER PRIMARY KEY AUTOINCREMENT, Kat_Nummer VARCHARE(10), Kat_Hauptnummer VARCHARE(10), Kat_Name VARCHARE(100))"
    10. db_Befehl.ExecuteNonQuery()
    11. db_Befehl.Dispose()
    12. DB_Verbindung.Close()
    13. DB_Verbindung.Open()
    14. db_Befehl = DB_Verbindung.CreateCommand
    15. db_Befehl.CommandText = "INSERT INTO Kategorie (Kat_Nummer, Kat_Hauptnummer, Kat_Name) VALUES ('K1000', '', 'Hauptkategorie 1')"
    16. db_Befehl.ExecuteReader()
    17. DB_Verbindung.Close()
    18. DB_Verbindung.Open()
    19. db_Befehl = DB_Verbindung.CreateCommand
    20. db_Befehl.CommandText = "INSERT INTO Kategorie (Kat_Nummer, Kat_Hauptnummer, Kat_Name) VALUES ('K1001', '', 'Hauptkategorie 2')"
    21. db_Befehl.ExecuteReader()
    22. DB_Verbindung.Close()
    23. DB_Verbindung.Open()
    24. db_Befehl = DB_Verbindung.CreateCommand
    25. db_Befehl.CommandText = "INSERT INTO Kategorie (Kat_Nummer, Kat_Hauptnummer, Kat_Name) VALUES ('K1002', 'K1001', 'Unterkategorie 1')"
    26. db_Befehl.ExecuteReader()
    27. DB_Verbindung.Close()
    28. DB_Verbindung.Open()
    29. db_Befehl = DB_Verbindung.CreateCommand
    30. db_Befehl.CommandText = "INSERT INTO Kategorie (Kat_Nummer, Kat_Hauptnummer, Kat_Name) VALUES ('K1003', 'K1001', 'Unterkategorie 2')"
    31. db_Befehl.ExecuteReader()
    32. DB_Verbindung.Close()
    33. DB_Verbindung.Open()
    34. db_Befehl = DB_Verbindung.CreateCommand
    35. db_Befehl.CommandText = "INSERT INTO Kategorie (Kat_Nummer, Kat_Hauptnummer, Kat_Name) VALUES ('K1004', 'K1002', 'Unter Unterkategorie 1')"
    36. db_Befehl.ExecuteReader()
    37. DB_Verbindung.Close()
    38. DB_Verbindung.Open()
    39. db_Befehl = DB_Verbindung.CreateCommand
    40. db_Befehl.CommandText = "INSERT INTO Kategorie (Kat_Nummer, Kat_Hauptnummer, Kat_Name) VALUES ('K1005', 'K1001', 'Unterkategorie 2')"
    41. db_Befehl.ExecuteReader()
    42. DB_Verbindung.Close()
    43. DB_Verbindung.Open()
    44. db_Befehl = DB_Verbindung.CreateCommand
    45. db_Befehl.CommandText = "INSERT INTO Kategorie (Kat_Nummer, Kat_Hauptnummer, Kat_Name) VALUES ('K1006', 'K1004', 'Unter Unter Unterkategorie 1')"
    46. db_Befehl.ExecuteReader()
    47. DB_Verbindung.Close()
    48. DB_Verbindung.Open()
    49. db_Befehl = DB_Verbindung.CreateCommand
    50. db_Befehl.CommandText = "INSERT INTO Kategorie (Kat_Nummer, Kat_Hauptnummer, Kat_Name) VALUES ('K1007', 'K1000', 'Unterkategorie 1')"
    51. db_Befehl.ExecuteReader()
    52. DB_Verbindung.Close()
    53. DB_Verbindung.Open()
    54. db_Befehl = DB_Verbindung.CreateCommand
    55. db_Befehl.CommandText = "INSERT INTO Kategorie (Kat_Nummer, Kat_Hauptnummer, Kat_Name) VALUES ('K1008', 'K1007', 'Unter Unterkategorie 1')"
    56. db_Befehl.ExecuteReader()
    57. DB_Verbindung.Close()
    58. DB_Verbindung.Open()
    59. db_Befehl = DB_Verbindung.CreateCommand
    60. db_Befehl.CommandText = "INSERT INTO Kategorie (Kat_Nummer, Kat_Hauptnummer, Kat_Name) VALUES ('K1009', 'K1007', 'Unter Unterkategorie 2')"
    61. db_Befehl.ExecuteReader()
    62. DB_Verbindung.Close()
    63. DB_Verbindung.Open()
    64. db_Befehl = DB_Verbindung.CreateCommand
    65. db_Befehl.CommandText = "INSERT INTO Kategorie (Kat_Nummer, Kat_Hauptnummer, Kat_Name) VALUES ('K1010', 'K1007', 'Unter Unterkategorie 3')"
    66. db_Befehl.ExecuteReader()
    67. DB_Verbindung.Close()
    68. End Sub
    69. Public Sub New()
    70. InitializeComponent()
    71. Dim Kategorie As List(Of KategorieKlasse) = New List(Of KategorieKlasse)()
    72. Dim DB_Verbindung As New System.Data.SQLite.SQLiteConnection
    73. Dim db_Befehl As System.Data.SQLite.SQLiteCommand
    74. DB_Verbindung.ConnectionString = "Data Source = kategorie.sdb"
    75. DB_Verbindung.Open()
    76. db_Befehl = DB_Verbindung.CreateCommand
    77. db_Befehl.CommandText = "SELECT Kat_Nummer, Kat_Hauptnummer, Kat_Name FROM Kategorie"
    78. Dim SQLreader As System.Data.SQLite.SQLiteDataReader = db_Befehl.ExecuteReader()
    79. While SQLreader.Read()
    80. If CType(SQLreader(1), String) = "" Then
    81. Dim Kategorie1 As KategorieKlasse = New KategorieKlasse() With {
    82. .KategorieName = CType(SQLreader(2), String),
    83. .KategorieNummer = CType(SQLreader(0), String)
    84. }
    85. Kategorie.Add(Kategorie1)
    86. Else
    87. Dim Kategorie2 As KategorieKlasse = New KategorieKlasse() With {
    88. .KategorieName = CType(SQLreader(2), String),
    89. .KategorieNummer = CType(SQLreader(0), String)
    90. }
    91. Kategorie.Add(Kategorie2)
    92. End If
    93. End While
    94. trv_Kategorie.ItemsSource = Kategorie
    95. End Sub
    96. Public Class KategorieKlasse
    97. Public Sub New()
    98. Me.UnterKategorie = New ObservableCollection(Of KategorieKlasse)()
    99. End Sub
    100. Public Property KategorieNummer As String
    101. Public Property KategorieName As String
    102. Public Property UnterKategorie As ObservableCollection(Of KategorieKlasse)
    103. End Class
    104. End Class


    So ist es schon mal besser oder?
    Nun zu die Unterkategorien bei WPF gibt es leider ein TreeNodes und komm irgendwie nicht weiter.
    wie meinst du das mit dem ObservableCollection(Of Kategorie)?
    Kannst du mir vielleicht ein beispiel liefern?

    dema schrieb:

    Was meinst du mit dem Helb-OOP-VB6-VB.Net ... ?
    Das steht doch im verlinkten Artikel, oder nicht?
    Den Expander "Warum das alles" klicksen und lesen.
    Und dann wirklich das tun, was da als nächstes steht:
    Noch einmal: Bitte guckt die Videos in Post#1 an - sind ziemlich am Schluss
    (das ist jetzt also noch nocheinmal).
    Und dann das tun, was im Video vorgeturnt ist.
    Erst danach ist dein System so eingestellt, dass du vb.net als objektorientierte streng typisierte Programmiersprache programmierst.

    Zu deim Datenzugriff habich doch (noch) kein Wort gesagt.
    Aber tatsächlich hier zB kann mans erkennen:

    VB.NET-Quellcode

    1. .KategorieName = SQLreader(2)
    Ich weiss, dass der Datentyp von SQLreader(2) Object ist, und in einer streng typisierten Sprache kann man einen Object-Wert nicht an eine String-Variable zuweisen - dieser Fehler darf vom Compiler nicht erlaubt werden.
    Aber im Schmuddel-Vb.net geht sowas eben doch, mit dem Ergebnis, dass du den Unterschied der Datentypen Object und String nicht wahrnimmst, und folglich auch nie verstehen kannst. (das war jetzt noch-noch-nocheinmal)



    ups - ich war zu spät - ja - fabelhaft, du hasts geschafft! :thumbsup:
    (Also du bist jetzt in der Ausgangslage, vb.net zu lernen.)

    Ich hab in der Zwischenzeit die "baumisierung" der Kategorie-Klasse betrieben:

    VB.NET-Quellcode

    1. Public Class Kategorie
    2. Public Shared Function CreateTree(kategorien As IEnumerable(Of Kategorie)) As ObservableCollection(Of Kategorie)
    3. Dim retVal = New ObservableCollection(Of Kategorie)
    4. Dim dic = kategorien.ToDictionary(Function(x) x.Nummer)
    5. ' bei Hauptkategorien ist die Parentnummer Nothing
    6. For Each k In kategorien
    7. If k.ParentNummer Is Nothing Then ' Unterkategorie
    8. dic(k.ParentNummer).UnterKategorien.Add(k) 'Parent-Kategorie holen, und ihren UnterKategorien adden
    9. Else
    10. retVal.Add(k) ' Hauptkategorie -> Ergebnisliste
    11. End If
    12. Next
    13. Return retVal
    14. End Function
    15. Public Property ParentNummer As String
    16. Public Property Nummer As String
    17. Public Property Name As String
    18. Public Property UnterKategorien As New ObservableCollection(Of Kategorie)
    19. End Class
    Es ist in der Klasse Kategorie selbst angelegt, als public Shared Function - die gibt dir die übergebenen Kategorien baumisiert in einer OC zurück (naja - steht da ja, im Code: Zeile #2 sagt genau das und nichts anderes aus).

    Ich hab auch gleich die Benamung vereinfacht und ver-leserlicht - ich hoffe, die Verbesserungen im Vergleich zu zuvor sind erkennbar.



    Hmm - aber in deim Code fehlt noch:

    ErfinderDesRades schrieb:

    Dein Einlesen musste auch soweit korrigieren, dasses funzt. In deine DB gibts 4 Properties, in deiner Kategorie-Klasse aber nur drei - und einlesen tuste nur zwei.
    Schreib ein Einlesen, was einfach eine flache Liste von kategorien erstellt.
    Am besten eine Methode, der du die Connection übergibst, und die eine ObservableCollection(Of Kategorie) returnt.


    Ein Beispiel hast du doch selbst. In zeile #99 - #114 befüllst du doch eine ObservableCollection(Of Kategorie) - nur machst du es falsch, indem du nur 2 von 4 erforderlichen Properties einträgst.
    Und dringend empfohlen, diesen Algorithmus in eine geeignete Methode auszulagern, anstatt die Sub New damit vollzuballern.

    Dieser Beitrag wurde bereits 10 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Hallo

    Hab es geändert aber ich bekomme jetzt keine Ausgabe,

    Die ID muss ich ja nicht auslesen da es ja nicht gebraucht wird. also müsste ich eigentlich nur die 3 Spalten auslesen

    hab mein Code so geändert aber anzeige gleich null

    VB.NET-Quellcode

    1. Imports System.Collections.ObjectModel
    2. Class MainWindow
    3. Public Sub New()
    4. InitializeComponent()
    5. Dim Kategorieneu As List(Of Kategorie) = New List(Of Kategorie)()
    6. Dim DB_Verbindung As New System.Data.SQLite.SQLiteConnection
    7. Dim db_Befehl As System.Data.SQLite.SQLiteCommand
    8. DB_Verbindung.ConnectionString = "Data Source = kategorie.sdb"
    9. DB_Verbindung.Open()
    10. db_Befehl = DB_Verbindung.CreateCommand
    11. db_Befehl.CommandText = "SELECT Kat_Nummer, Kat_Hauptnummer, Kat_Name FROM Kategorie"
    12. Dim SQLreader As System.Data.SQLite.SQLiteDataReader = db_Befehl.ExecuteReader()
    13. While SQLreader.Read()
    14. Dim Kategorie1 As Kategorie = New Kategorie() With {
    15. .Nummer = CType(SQLreader(0), String),
    16. .ParentNummer = CType(SQLreader(1), String),
    17. .Name = CType(SQLreader(2), String)}
    18. Kategorieneu.Add(Kategorie1)
    19. End While
    20. trv_Kategorie.ItemsSource = Kategorieneu
    21. End Sub
    22. End Class
    23. Public Class Kategorie
    24. Public Shared Function CreateTree(kategorien As IEnumerable(Of Kategorie)) As ObservableCollection(Of Kategorie)
    25. Dim retVal = New ObservableCollection(Of Kategorie)
    26. Dim dic = kategorien.ToDictionary(Function(x) x.Nummer)
    27. For Each k In kategorien.Where(Function(x) x.ParentNummer IsNot Nothing)
    28. dic(k.ParentNummer).UnterKategorien.Add(k)
    29. Next
    30. For Each k In kategorien.Where(Function(x) x.ParentNummer Is Nothing)
    31. retVal.Add(k)
    32. Next
    33. Return retVal
    34. End Function
    35. Public Sub New()
    36. Me.UnterKategorien = New ObservableCollection(Of Kategorie)()
    37. End Sub
    38. Public Property ParentNummer As String
    39. Public Property Nummer As String
    40. Public Property Name As String
    41. Public Property UnterKategorien As ObservableCollection(Of Kategorie)
    42. End Class

    dema schrieb:

    Die ID muss ich ja nicht auslesen da es ja nicht gebraucht wird. also müsste ich eigentlich nur die 3 Spalten auslesen
    Prinzipiell wenn man mit Datensätzen arbeitet, muss die ID mit.
    Braucht man für nix, aber zum Abspeichern braucht mans doch.

    Keine Anzeige? Dann ruf meine Methode auch auf, und setze die ItemsSource:

    VB.NET-Quellcode

    1. trv_Kategorie.ItemsSource = Kategorie.CreateTree(Kategorieneu)
    hope it helps.

    Übrigens hab ich die Klasse Kategorie insgesamt noch weiter verhübscht und kommentiert - guck nochmal nach.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Danke jetzt wird es zwar angezeigt aber die Unterkategorien werden immer noch nicht zugeordnet sehe Bild

    mein CODE

    WPF:

    Quellcode

    1. <Window x:Class="MainWindow"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    6. xmlns:local="clr-namespace:MvvM_Treeview"
    7. mc:Ignorable="d"
    8. Title="MainWindow" Height="450" Width="488.952">
    9. <Grid>
    10. <TreeView Name="trv_Kategorie">
    11. <TreeView.ItemTemplate>
    12. <HierarchicalDataTemplate ItemsSource="{Binding CreateTree}">
    13. <StackPanel Orientation="Horizontal">
    14. <TextBlock Text="{Binding Nummer}" Margin="0,0,4,0" />
    15. <TextBlock Text="{Binding Name}" Margin="0,0,4,0" />
    16. </StackPanel>
    17. </HierarchicalDataTemplate>
    18. </TreeView.ItemTemplate>
    19. </TreeView>
    20. </Grid>
    21. </Window>


    VB.NET:

    VB.NET-Quellcode

    1. Imports System.Collections.ObjectModel
    2. Class MainWindow
    3. Public Sub New()
    4. InitializeComponent()
    5. Dim Kategorieneu As List(Of Kategorie) = New List(Of Kategorie)()
    6. Dim DB_Verbindung As New System.Data.SQLite.SQLiteConnection
    7. Dim db_Befehl As System.Data.SQLite.SQLiteCommand
    8. DB_Verbindung.ConnectionString = "Data Source = kategorie.sdb"
    9. DB_Verbindung.Open()
    10. db_Befehl = DB_Verbindung.CreateCommand
    11. db_Befehl.CommandText = "SELECT Kat_Nummer, Kat_Hauptnummer, Kat_Name FROM Kategorie"
    12. Dim SQLreader As System.Data.SQLite.SQLiteDataReader = db_Befehl.ExecuteReader()
    13. While SQLreader.Read()
    14. Dim Kategorie1 As Kategorie = New Kategorie() With {
    15. .Nummer = CType(SQLreader(0), String),
    16. .ParentNummer = CType(SQLreader(1), String),
    17. .Name = CType(SQLreader(2), String)}
    18. Kategorieneu.Add(Kategorie1)
    19. End While
    20. trv_Kategorie.ItemsSource = Kategorie.CreateTree(Kategorieneu)
    21. End Sub
    22. End Class
    23. Public Class Kategorie
    24. Public Shared Function CreateTree(kategorien As IEnumerable(Of Kategorie)) As ObservableCollection(Of Kategorie)
    25. Dim retVal = New ObservableCollection(Of Kategorie)
    26. Dim dic = kategorien.ToDictionary(Function(x) x.Nummer)
    27. ' bei Hauptkategorien ist die Parentnummer Nothing
    28. For Each k In kategorien
    29. If k.ParentNummer Is Nothing Then ' Unterkategorie
    30. dic(k.ParentNummer).UnterKategorien.Add(k) 'Parent-Kategorie holen, und ihren UnterKategorien adden
    31. Else
    32. retVal.Add(k) ' Hauptkategorie -> Ergebnisliste
    33. End If
    34. Next
    35. Return retVal
    36. End Function
    37. Public Property ParentNummer As String
    38. Public Property Nummer As String
    39. Public Property Name As String
    40. Public Property UnterKategorien As New ObservableCollection(Of Kategorie)
    41. End Class
    Bilder
    • Anzeige_Treeview.JPG

      32,3 kB, 475×442, 11 mal angesehen
    Jo, inne Methode issn logischer Fehler - Probierma:

    VB.NET-Quellcode

    1. Public Shared Function CreateTree(kategorien As IEnumerable(Of Kategorie)) As ObservableCollection(Of Kategorie)
    2. Dim retVal = New ObservableCollection(Of Kategorie)
    3. Dim dic = kategorien.ToDictionary(Function(x) x.Nummer)
    4. ' bei Hauptkategorien ist die Parentnummer leer
    5. For Each k In kategorien
    6. If k.ParentNummer <> "" Then ' Unterkategorie
    7. dic(k.ParentNummer).UnterKategorien.Add(k) 'Parent-Kategorie holen, und ihren UnterKategorien adden
    8. Else
    9. retVal.Add(k) ' Hauptkategorie -> Ergebnisliste
    10. End If
    11. Next
    12. Return retVal
    13. End Function

    Ich kann hier ja nix testen.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()