Treeview mit Checkboxen, ...speichern, laden und markieren

  • VB.NET

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von lris08.

    Treeview mit Checkboxen, ...speichern, laden und markieren

    Hallo VB'ler :)

    Ich sitze schon seit Monaten vor einem Problem mit nem Treeview... ich verschiebs immer wieder, aber nun komme ich nicht mehr darum herum :)

    Ich lade in einem Treeview Kategorien mit folgendem Code:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Sub Kategorie_Laden()
    2. TreeView1.Nodes.Clear()
    3. Dim dt As DataTable = New DataTable("TreeView")
    4. Me.TV1_Datentabelle_fuellen(dt)
    5. Me.TV1_HauptNode_fuellen(dt)
    6. Me.TreeView1.Sort()
    7. Me.TreeView1.CollapseAll()
    8. End Sub
    9. Public Sub TV1_Datentabelle_fuellen(ByRef dt As DataTable)
    10. Try
    11. Dim sCN As String = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source =" & Archiv_aktiv & "; Jet OLEDB:database Password=" & DBPasswort & ";"
    12. Dim sql As String = "SELECT * FROM " & Tabelle08 & " ORDER BY ID"
    13. Dim cn As OleDb.OleDbConnection = New OleDb.OleDbConnection(sCN)
    14. Dim da As OleDb.OleDbDataAdapter = New OleDb.OleDbDataAdapter(sql, cn)
    15. Dim cmd As OleDb.OleDbCommandBuilder = New OleDb.OleDbCommandBuilder(da)
    16. da.Fill(dt)
    17. Catch ex As OleDb.OleDbException
    18. Fehlermeldung = ex.Message & " - Fehler: Schnellablage, TV1_Datentabelle_fuellen "
    19. Fehler_Instance.Ausgabe(Fehlermeldung)
    20. Exit Sub
    21. End Try
    22. End Sub
    23. Public Sub TV1_HauptNode_fuellen(ByVal dt As DataTable)
    24. Me.TreeView1.BeginUpdate()
    25. 'Dim ParentId As Integer
    26. Dim Tn As TreeNode
    27. For Each r As DataRow In dt.Rows
    28. Tn = New TreeNode((r("Kat_Tag").ToString))
    29. Tn.Tag = (r("ID").ToString)
    30. Tn.ImageIndex = 0
    31. Tn.SelectedImageIndex = 1
    32. If Convert.ToInt32(r("Kat_ParentID")) = 0 Then
    33. Me.TreeView1.Nodes.Add(Tn)
    34. End If
    35. TV1_SubNode_fuellen(Tn, dt, Convert.ToInt32(r("ID")))
    36. Next
    37. Me.TreeView1.EndUpdate()
    38. End Sub
    39. Public Sub TV1_SubNode_fuellen(ByRef tn As TreeNode, ByRef dt As DataTable, ByVal ID As Integer)
    40. Dim foundRows() As DataRow = dt.Select("Kat_ParentID = " + ID.ToString, "ID")
    41. Dim Tn_Sub As TreeNode
    42. For Each _r As DataRow In foundRows
    43. Tn_Sub = New TreeNode((_r("Kat_Tag").ToString))
    44. Tn_Sub.Tag = (_r("ID").ToString)
    45. Tn_Sub.ImageIndex = 0
    46. Tn_Sub.SelectedImageIndex = 1
    47. tn.Nodes.Add(Tn_Sub)
    48. TV1_SubNode_fuellen(Tn_Sub, dt, Convert.ToInt32(_r("ID")))
    49. Next
    50. End Sub


    Bisher kann ich immer nur eine Kategorie in meine Datenbank speichern... so:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public IDs() As String
    2. Public IDvergleich() As String
    3. Private Sub TreeView1_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect
    4. Timer1.Start()
    5. Aufb_Bz = ""
    6. Aufb_YY = 0
    7. ' Array 1 füllen
    8. Erase IDs
    9. ReDim Preserve IDs(0)
    10. IDs(0) = e.Node.Tag
    11. 'Array2 füllen
    12. Erase IDvergleich
    13. ReDim Preserve IDvergleich(0)
    14. IDvergleich(0) = e.Node.Tag
    15. Erase IDvergleich
    16. DGV1_Daten()
    17. 'Daten für Neuanlage Dokumentenmappe
    18. Dim Kat_ID As Integer = e.Node.Tag
    19. Dim con As New OleDb.OleDbConnection
    20. Dim cmd As New OleDb.OleDbCommand
    21. Dim reader As OleDb.OleDbDataReader
    22. con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source =" & Archiv_aktiv & "; Jet OLEDB:database Password=" & DBPasswort & ";"
    23. cmd.Connection = con
    24. cmd.CommandText = "SELECT * FROM " & Tabelle08 & " WHERE ID = " & Kat_ID
    25. Try
    26. con.Open()
    27. reader = cmd.ExecuteReader()
    28. Do While reader.Read()
    29. Kategorie = reader("ID")
    30. Aufb_YY = reader("Kat_AufbewahrungYY").ToString()
    31. Aufb_Bz = reader("Kat_AufbewahrungBez").ToString()
    32. Loop
    33. con.Close()
    34. Catch ex As Exception
    35. Fehlermeldung = ex.Message & " - Fehler: Schnellablage, TreeView1_AfterSelect - 1"
    36. Fehler_Instance.Ausgabe(Fehlermeldung)
    37. Exit Sub
    38. Finally
    39. con.Close()
    40. ToolStripProgressBar1.Value = 100
    41. End Try
    42. End Sub
    43. ...
    44. Dim con As New OleDb.OleDbConnection
    45. Dim cmd As New OleDb.OleDbCommand
    46. con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" & Archiv_aktiv & "; Jet OLEDB:database Password=" & DBPasswort & ";"
    47. cmd.Connection = con
    48. cmd.CommandText = "INSERT into " & Tabelle02 & " (Map_Bezeichnung, Map_Kategorie, Map_ErstelltDatum, Map_AenderungDatum, Map_ErstelltUser, Map_GeaendertUser, Map_Status, Map_Aktenschrank, Map_Ordner, Map_AufbewahrungJahre, Map_AufbewahrungKategorie, Map_Prio, Map_Rechnung, Map_RgNummer, Map_Betrag, Map_RgDatum, Map_VergleichDateTime, Map_Provision, Map_Art, Map_WebSync, Map_WS_VerfallDat) " & _
    49. "VALUES ('" & TextBox1.Text & "', '" & CStr(Kategorie) & "',......................


    Nun möchte ich es aber so machen, dass ich eine eigene Datenbanktabelle anlege, in der passen zur Akte dann die Kategorien stehen:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. ID Akte Kategorie Status
    2. 1 222 10 A
    3. 2 222 88 A
    4. 3 222 123 A
    5. 4 310 10 A
    6. 5 310 21 A
    7. usw


    Ich habe schon viel über die Checkboxen in einem Treeview gelesen, komme damit aber überhaupt nicht zu recht...

    Hätte es mir so vorgestellt, dass ich die checkboxen im Treeview markiere, beim speichern er dann alle markieren Checkboxen im Treeview nacheinander in die neue Datenbanltablle schreibt.
    Beim öffnen der "Akte" sollen dann in der neuen Datenbanktabelle alle gespeicherten Nr. der Treeview-Checkboxen wieder geladen werden und die Checkboxen im Treeview wieder einen Hacken bekommen.

    Ich kann mir vorstellen, dass dies eigentlich gar nicht so schwer ist umzusetzen... nur ich verstehs einfach nicht ... vorllem die zusammenhänge und das gesamte Verhalten von den Checkboxen im Treeview überhaupt...


    Könntet Ihr mir da behilflich sein ??

    Wäre super nett... vielen dank vorab...

    lris
    schau mal

    VB.NET-Quellcode

    1. Private Sub TreeView_Adressen_AfterCheck(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView_Adressen.AfterCheck
    2. ' Vorhanden = Nein
    3. Dim Vorahnden As Boolean = False
    4. ' Wenn die Node Checked Ist
    5. If e.Node.Checked = True Then


    über e müsstest du dran kommen
    ich peile dein Datenmodell nicht.
    es scheint iwie eine Tabelle Kategorie zu geben, und die ist rekursiv mit sich selbst verknüpft.

    Und eine Akte?? Tabelle08??, deren DataRows diesen Kategorien zugeordnet sind.

    Ich hab mal sowas mit einer foto-DB gemacht, da konnte man Kategorien selbst erstellen, etwa Arbeit, Familie, Großgruppen, Kleingruppen, Portraits, bis hin zu einzelne Namen.
    Und Großgruppe, Kleingruppe, Portrait war natürlich verschachtelt, also ein Portrait ist eine Kleingruppen-Aufnahme ist eine Großgruppen-Aufnahme.
    Ist deine Kategorien-Logik auch so?

    Daraus ergibt sich nämlich ein bestimmtes Selektierungs-Verhalten der TreeNodes, weil wennich die Kleingruppen-Node checke, muß dessen Parent (Großgruppe) auch gecheckt wern, aber nicht das Portrait.

    War wichtig für Such-Abfragen.

    Also einzelne Kategorien habichnich abgespeichert. Ich hab immer die ganze Kategorie-Table geladen, und daraus den Treeview gebaut.
    Die TreeNodes waren mit KategoryRows verknüppert und synchronisiert.
    Dann konnteman im Treeview rumfuhrwerken nach belieben, und die DataTable veränderte sich dazu synchron.
    Zum Schluß wurde das ganze Teil wieder in die DB geschupst.

    Wie gesagt, bei dir blickt man weder durchs Datenmodell durch, noch, was die App dann können soll (auch Kategorien erzeugen/löschen/verschieben? auch Suchabfragen aus Kategorien zusammenstöpseln und abfahren?)
    hallo

    danke für eure anworten :)

    glaube schonb, dass mein Code nicht gerade der beste ist... und nachvollzogen werden kann. bin ja nur hobbyprog. aber gebe mit mühe...


    habe mir nun so beim putzen heute mal gedacht, eigentlich brauche ich doch nur die gecheckten treeview-checkboxen durchlaufen lassen, wer true ist - ausgeben lassen und z.b in einem list(of string) speichern, oder ?

    mit diesem code habe ich nun mein glück versucht:

    VB.NET-Quellcode

    1. Dim Categories As New ArrayList 'List(Of String())
    2. Private Sub TreeView1_AfterCheck(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterCheck
    3. For Each child As TreeNode In e.Node.Nodes
    4. child.Checked = e.Node.Checked
    5. Next
    6. ' expand all childs falls checked
    7. If e.Node.Checked Then e.Node.ExpandAll()
    8. For Each tn As TreeNode In TreeView1.Nodes
    9. If tn.Checked Then
    10. Categories.Add(tn.Tag)
    11. End If
    12. Next
    13. For Each f As String In Categories
    14. MsgBox(f) ' erstmal zum Testen als Textbox ausgeben...
    15. Next
    16. End Sub


    also das funktioniert schon mal - ABER, leider nur mit einem "hauptknoten"... die kinder :) davon werden anscheinend nicht abgefragt.
    durchläuft der o.g. code nicht das gesamte treeview ??

    viele grüße
    lris

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

    ich verstehe die Logik ühaupt nicht: Wenn du einen Node checkst, sollen Categories geadded werden??

    Also bei mir gabs Kategorien und Bilder. Und alle Kategorien wurden in einem TreeView dargestellt - da war zunächstmal nix mit adden.
    Man wählte also ein Bild an, und wenn man dann eine Kategorie checkte, dann wurde eine Zuordnung erzeugt, die aussagte: "Diese Kategorie ist diesem bild zugeordnet."
    Diese Zuordnungen waren Extra-Datensätze in einer Extra-DataTable.

    Da bin ich sehr stolz drauf, weil das habichmir selbst so ausgedacht, und Jahre später habichdann gelernt, dass das das Standard-Vorgehen ist, wenn man eine m:n - Relation modelliert.

    Also erklärmal genauer, was das mit dem NodeCheck und dem Category-Adden auf sich hat.
    Habs nun endlich hinbekommen... ein Teil von meinem Problem ist beseitigt :)

    Wenns mal jemand brauchen kann, hier der Code:

    VB.NET-Quellcode

    1. Private IDs() As String
    2. Private Sub TreeView1_AfterCheck(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterCheck
    3. For Each child As TreeNode In e.Node.Nodes
    4. child.Checked = e.Node.Checked
    5. Next
    6. If e.Node.Checked Then e.Node.ExpandAll()
    7. Erase IDs
    8. ReDim Preserve IDs(0)
    9. Kategorien_Uebernehmen()
    10. DGV1_fuellen(9, "")
    11. End Sub
    12. Private Sub Kategorien_Uebernehmen()
    13. Dim i As Integer = 0
    14. For Each Items As TreeNode In TreeView_GetSelectedNodes(Me.TreeView1.Nodes)
    15. ReDim Preserve IDs(i)
    16. IDs(i) = Items.Tag
    17. i += 1
    18. Next
    19. End Sub
    20. Private Function TreeView_GetSelectedNodes(ByVal Nodes As TreeNodeCollection) As ArrayList
    21. Dim TList As New ArrayList
    22. For Each Items As TreeNode In Nodes
    23. If Items.Checked Then TList.Add(Items)
    24. TList.AddRange(TreeView_GetSelectedNodes(Items.Nodes))
    25. Next
    26. Return TList
    27. End Function