Benutzer mit den meisten Antworten
Treeview mit Daten aus Access-Datenbank füllen

Frage
-
Hallo,
ich möchte meinem aktuellen Projekt ein weiteres Fenster mit einer TreeView-Control hinzufügen. Die Daten, die im TreeView angezeigt werden sollen, sind Bereiche, Kategorien innerhalb der Bereiche und Objekte innerhalb der Kategorien. Ich habe mir eine Instanz meines Datenbank-DataSets erstellt und über Adapter das DataSet gefüllt:Dim dsBereichKategorie As New planerDataSet Dim taBereich As New planerDataSetTableAdapters.tblbereichTableAdapter Dim taKategorie As New planerDataSetTableAdapters.tblkategorieTableAdapter Dim taObjekt As New planerDataSetTableAdapters.tblobjektTableAdapter taBereich.Fill(dsBereichKategorie.tblbereich) taKategorie.Fill(dsBereichKategorie.tblkategorie) taObjekt.Fill(dsBereichKategorie.tblobjekt)
Jetzt wollte ich eigentlich mit Hilfe von LINQ to DataSet das Treeview füllen, aber da kommt zurzeit nur heiße Luft :-(. Habt Ihr eine Idee, wie es weiter geht? Tausend Dank im Voraus für Eure Hilfe!
Gruß
Marcus
Der erste Tag, an dem ich nichts Neues lerne, wird der Tag sein, an dem sich der Deckel über mir schließt...
Antworten
-
Hallo Marcus,
unten das ganze (untypisiert) via LINQ To DataSet.
Einige Ausdrücke lassen sich mit typisierten DataSets vereinfachen, siehe Abfragen von typisierten DataSets
und sehen dann nicht mehr ganz so umständlich aus ;-)Ich habe exemplarisch über "aktiv" gefiltert.
Denkbar wäre zwar, alles in einer (geschachtelten) Query zusammenzufassen,
das ist aber nicht unbedingt verständlicher...Eine weitere Lektüre von Informationen zum Programmieren (LINQ to DataSet) ist zu empfehlen,
so nicht bereits angelesen.Was die ImageList angeht: Solange Du nicht jedem Knoten ein anderes Bild zuweisen willst,
reicht eine Zuordnung von Treeview.ImageIndex und TreeView. SelectedImageIndex.
Dort in der MSDN findet sich ein Beispiel, wie man es auf Knotenebene hinunter festlegen kann.Das Formular besteht aus einem TreeView1 und einer TextBox1 -
mit letzterer wird für das Auswählen eines Objekts gezeigt,
wie man sich via JOIN alle Daten zusammenholen kann.Imports System.Linq Public Class TreeViewForm Private planerDataSet As DataSet Private Sub TreeViewForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Erstellen des DataSets (hier untypisiert) planerDataSet = CreateDataSet() ' typisiert wäre: dsBereichKategorie.tblbereich ' mehr http://msdn.microsoft.com/de-de/library/bb399351.aspx Dim bereichQuery = From b In planerDataSet.Tables("tblBereich").AsEnumerable() _ Let BereichId = b.Field(Of Integer)("bereichid") _ Where b.Field(Of Boolean)("aktiv") = True _ Order By BereichId _ Select BereichId, Bereich = b.Field(Of String)("Bereich") For Each bereichRow In bereichQuery Dim bereichid = bereichRow.BereichId ' in lokale Variable speichern ' Abfrage Kategorien im Bereich Dim kategorieQuery = From k In planerDataSet.Tables("tblKategorie").AsEnumerable() _ Let KategorieId = k.Field(Of Integer)("kategorieid") _ Where k.Field(Of Integer)("bereichid") = bereichid _ AndAlso k.Field(Of Boolean)("aktiv") = True Order By KategorieId _ Select KategorieId, Kategorie = k.Field(Of String)("Kategorie") Dim bereichNode = Me.TreeView1.Nodes.Add(bereichRow.Bereich) For Each kategorieRow In kategorieQuery Dim kategorieid = kategorieRow.KategorieId ' Abfrage Objekt in Kategorie Dim objektQuery = From o In planerDataSet.Tables("tblobjekt").AsEnumerable() _ Let ObjektId = o.Field(Of Integer)("objektid") _ Let ObjektNummer = o.Field(Of String)("objektnr") _ Where o.Field(Of Integer)("kategorieid") = kategorieid _ Order By ObjektNummer _ Select ObjektId, Bezeichnung = ObjektNummer & " " & o.Field(Of String)("objektbezeichnung") Dim kategorieNode = bereichNode.Nodes.Add(kategorieRow.Kategorie) For Each objektRow In objektQuery With kategorieNode.Nodes.Add(objektRow.Bezeichnung) .Tag = objektRow.ObjektId ' Für späteres Nachschlagen ' für alternative Bilder ' .ImageIndex = ' .SelectedImageIndex = End With Next Next Next End Sub Private Sub TreeView1_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect If e.Node IsNot Nothing Then Dim objektid = CInt(e.Node.Tag) ' Mehr als Illustration für einen Join Dim objektQuery = From o In planerDataSet.Tables("tblobjekt").AsEnumerable() _ Join k In planerDataSet.Tables("tblkategorie").AsEnumerable() _ On o.Field(Of Integer)("kategorieid") Equals k.Field(Of Integer)("kategorieid") _ Join b In (planerDataSet.Tables("tblbereich").AsEnumerable()) _ On b.Field(Of Integer)("bereichid") Equals k.Field(Of Integer)("bereichid") _ Where o.Field(Of Integer)("objektid") = objektid Select Bezeichnung = b.Field(Of String)("bereich") & "-" & _ k.Field(Of String)("kategorie") & "-" & _ o.Field(Of String)("objektbezeichnung") Dim anzeigeText = objektQuery.SingleOrDefault() Me.TextBox1.Text = anzeigeText End If End Sub #Region "CreateDataSet" Private Shared Function CreateDataSet() As DataSet Dim dataSet As New DataSet("planerDataSet") ' tblBereich erstellen Dim bereichTable = dataSet.Tables.Add("tblBereich") bereichTable.Columns.AddRange(New DataColumn() { _ New DataColumn("bereichid", GetType(Integer)), _ New DataColumn("bereich", GetType(String)), _ New DataColumn("aktiv", GetType(Boolean))}) ' PrimaryKey Dim bereichId = bereichTable.Columns("bereichid") bereichTable.PrimaryKey = New DataColumn() {bereichId} ' tblKategorie erstellen Dim kategorieTable = dataSet.Tables.Add("tblKategorie") kategorieTable.Columns.AddRange(New DataColumn() { _ New DataColumn("kategorieid", GetType(Integer)), _ New DataColumn("kategorie", GetType(String)), _ New DataColumn("bereichid", GetType(Integer)), _ New DataColumn("aktiv", GetType(Boolean))}) ' PrimaryKey Dim kategorieId = kategorieTable.Columns("kategorieId") kategorieTable.PrimaryKey = New DataColumn() {kategorieId} ' Relation Dim kategorieBereichId = kategorieTable.Columns("bereichid") dataSet.Relations.Add("BereichKategorieRelation", bereichId, kategorieBereichId, True) ' tblObjekt erstellen (Spalten verkürzt) Dim objektTable = dataSet.Tables.Add("tblObjekt") objektTable.Columns.AddRange(New DataColumn() { _ New DataColumn("objektid", GetType(Integer)), _ New DataColumn("objektnr", GetType(String)), _ New DataColumn("objektbezeichnung", GetType(String)), _ New DataColumn("kategorieid", GetType(Integer)), _ New DataColumn("bereichid", GetType(Integer))}) ' PrimaryKey Dim objektId = kategorieTable.Columns("objektid") objektTable.PrimaryKey = New DataColumn() {objektId} ' Relation (Ohne Bereich, denn das wäre doppelt gehoppelt ;-) Dim objektKategorieId = objektTable.Columns("kategorieid") dataSet.Relations.Add("KategorieObjektRelation", kategorieId, objektKategorieId, True) ' Beispieldaten erzeugen bereichTable.Rows.Add(1, "1. Bereich", True) bereichTable.Rows.Add(2, "2. Bereich", False) ' nicht aktiv bereichTable.Rows.Add(3, "3. Bereich", True) kategorieTable.Rows.Add(10, "Kategorie 10", 1, True) kategorieTable.Rows.Add(11, "Kategorie 11", 1, False) ' nicht aktiv kategorieTable.Rows.Add(12, "Kategorie 12", 1, True) kategorieTable.Rows.Add(20, "Kategorie 20", 2, True) kategorieTable.Rows.Add(21, "Kategorie 21", 2, False) kategorieTable.Rows.Add(30, "Kategorie 30", 3, True) kategorieTable.Rows.Add(31, "Kategorie 31", 3, True) kategorieTable.Rows.Add(32, "Kategorie 32", 3, True) objektTable.Rows.Add(101, "Nr 101", "Objekt 101", 10, 1) objektTable.Rows.Add(102, "Nr 102", "Objekt 102", 10, 1) objektTable.Rows.Add(111, "Nr 111", "Objekt 111", 11, 1) objektTable.Rows.Add(121, "Nr 121", "Objekt 121", 12, 1) objektTable.Rows.Add(301, "Nr 301", "Objekt 301", 30, 1) objektTable.Rows.Add(311, "Nr 311", "Objekt 311", 31, 1) objektTable.Rows.Add(321, "Nr 311", "Objekt 321", 32, 1) Return dataSet End Function #End Region End Class
Nachhaken, falls Unklarheiten bestehen.
Gruß Elmar
- Als Antwort markiert mjanz Donnerstag, 9. September 2010 13:31
Alle Antworten
-
Hallo Elmar,
die drei Tabellen sehen so aus:
tblbereich:
bereichid (int)
bereich (nvarchar)
aktiv (bit)tblkategorie:
kategorieid (int)
kategorie (nvarchar)
bereichid (int)
aktiv (bit)tblobjekt:
objektid (int)
objektnummer (nvarchar)
objektbezeichnung (nvarchar)
objektbeschreibung (nvarchar)
bereichid (int)
kategorieid (int)
angelegt (date)
autor (nvarchar)
Das typisierte DataSet heißt planerDataSet.Das Treeview-Steuerelement stelle ich mir so vor:
Bereich (Anzahl der enthaltenden Kategorien)
- Kategorie (Anzahl der enthaltenen Objekte)
-- [Objektnummer] Objektbezeichnung
Ich würde gerne mit einer ImageList arbeiten. Einen geschlossenen Ordner, wenn eine Knoten geschlossen ist und einen offenen Ordner, wenn der Knoten expandiert ist. Ich hoffe, Du kannst etwas damit anfangen...
Gruß
Marcus
Der erste Tag, an dem ich nichts Neues lerne, wird der Tag sein, an dem sich der Deckel über mir schließt... -
Hallo Marcus,
unten das ganze (untypisiert) via LINQ To DataSet.
Einige Ausdrücke lassen sich mit typisierten DataSets vereinfachen, siehe Abfragen von typisierten DataSets
und sehen dann nicht mehr ganz so umständlich aus ;-)Ich habe exemplarisch über "aktiv" gefiltert.
Denkbar wäre zwar, alles in einer (geschachtelten) Query zusammenzufassen,
das ist aber nicht unbedingt verständlicher...Eine weitere Lektüre von Informationen zum Programmieren (LINQ to DataSet) ist zu empfehlen,
so nicht bereits angelesen.Was die ImageList angeht: Solange Du nicht jedem Knoten ein anderes Bild zuweisen willst,
reicht eine Zuordnung von Treeview.ImageIndex und TreeView. SelectedImageIndex.
Dort in der MSDN findet sich ein Beispiel, wie man es auf Knotenebene hinunter festlegen kann.Das Formular besteht aus einem TreeView1 und einer TextBox1 -
mit letzterer wird für das Auswählen eines Objekts gezeigt,
wie man sich via JOIN alle Daten zusammenholen kann.Imports System.Linq Public Class TreeViewForm Private planerDataSet As DataSet Private Sub TreeViewForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Erstellen des DataSets (hier untypisiert) planerDataSet = CreateDataSet() ' typisiert wäre: dsBereichKategorie.tblbereich ' mehr http://msdn.microsoft.com/de-de/library/bb399351.aspx Dim bereichQuery = From b In planerDataSet.Tables("tblBereich").AsEnumerable() _ Let BereichId = b.Field(Of Integer)("bereichid") _ Where b.Field(Of Boolean)("aktiv") = True _ Order By BereichId _ Select BereichId, Bereich = b.Field(Of String)("Bereich") For Each bereichRow In bereichQuery Dim bereichid = bereichRow.BereichId ' in lokale Variable speichern ' Abfrage Kategorien im Bereich Dim kategorieQuery = From k In planerDataSet.Tables("tblKategorie").AsEnumerable() _ Let KategorieId = k.Field(Of Integer)("kategorieid") _ Where k.Field(Of Integer)("bereichid") = bereichid _ AndAlso k.Field(Of Boolean)("aktiv") = True Order By KategorieId _ Select KategorieId, Kategorie = k.Field(Of String)("Kategorie") Dim bereichNode = Me.TreeView1.Nodes.Add(bereichRow.Bereich) For Each kategorieRow In kategorieQuery Dim kategorieid = kategorieRow.KategorieId ' Abfrage Objekt in Kategorie Dim objektQuery = From o In planerDataSet.Tables("tblobjekt").AsEnumerable() _ Let ObjektId = o.Field(Of Integer)("objektid") _ Let ObjektNummer = o.Field(Of String)("objektnr") _ Where o.Field(Of Integer)("kategorieid") = kategorieid _ Order By ObjektNummer _ Select ObjektId, Bezeichnung = ObjektNummer & " " & o.Field(Of String)("objektbezeichnung") Dim kategorieNode = bereichNode.Nodes.Add(kategorieRow.Kategorie) For Each objektRow In objektQuery With kategorieNode.Nodes.Add(objektRow.Bezeichnung) .Tag = objektRow.ObjektId ' Für späteres Nachschlagen ' für alternative Bilder ' .ImageIndex = ' .SelectedImageIndex = End With Next Next Next End Sub Private Sub TreeView1_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect If e.Node IsNot Nothing Then Dim objektid = CInt(e.Node.Tag) ' Mehr als Illustration für einen Join Dim objektQuery = From o In planerDataSet.Tables("tblobjekt").AsEnumerable() _ Join k In planerDataSet.Tables("tblkategorie").AsEnumerable() _ On o.Field(Of Integer)("kategorieid") Equals k.Field(Of Integer)("kategorieid") _ Join b In (planerDataSet.Tables("tblbereich").AsEnumerable()) _ On b.Field(Of Integer)("bereichid") Equals k.Field(Of Integer)("bereichid") _ Where o.Field(Of Integer)("objektid") = objektid Select Bezeichnung = b.Field(Of String)("bereich") & "-" & _ k.Field(Of String)("kategorie") & "-" & _ o.Field(Of String)("objektbezeichnung") Dim anzeigeText = objektQuery.SingleOrDefault() Me.TextBox1.Text = anzeigeText End If End Sub #Region "CreateDataSet" Private Shared Function CreateDataSet() As DataSet Dim dataSet As New DataSet("planerDataSet") ' tblBereich erstellen Dim bereichTable = dataSet.Tables.Add("tblBereich") bereichTable.Columns.AddRange(New DataColumn() { _ New DataColumn("bereichid", GetType(Integer)), _ New DataColumn("bereich", GetType(String)), _ New DataColumn("aktiv", GetType(Boolean))}) ' PrimaryKey Dim bereichId = bereichTable.Columns("bereichid") bereichTable.PrimaryKey = New DataColumn() {bereichId} ' tblKategorie erstellen Dim kategorieTable = dataSet.Tables.Add("tblKategorie") kategorieTable.Columns.AddRange(New DataColumn() { _ New DataColumn("kategorieid", GetType(Integer)), _ New DataColumn("kategorie", GetType(String)), _ New DataColumn("bereichid", GetType(Integer)), _ New DataColumn("aktiv", GetType(Boolean))}) ' PrimaryKey Dim kategorieId = kategorieTable.Columns("kategorieId") kategorieTable.PrimaryKey = New DataColumn() {kategorieId} ' Relation Dim kategorieBereichId = kategorieTable.Columns("bereichid") dataSet.Relations.Add("BereichKategorieRelation", bereichId, kategorieBereichId, True) ' tblObjekt erstellen (Spalten verkürzt) Dim objektTable = dataSet.Tables.Add("tblObjekt") objektTable.Columns.AddRange(New DataColumn() { _ New DataColumn("objektid", GetType(Integer)), _ New DataColumn("objektnr", GetType(String)), _ New DataColumn("objektbezeichnung", GetType(String)), _ New DataColumn("kategorieid", GetType(Integer)), _ New DataColumn("bereichid", GetType(Integer))}) ' PrimaryKey Dim objektId = kategorieTable.Columns("objektid") objektTable.PrimaryKey = New DataColumn() {objektId} ' Relation (Ohne Bereich, denn das wäre doppelt gehoppelt ;-) Dim objektKategorieId = objektTable.Columns("kategorieid") dataSet.Relations.Add("KategorieObjektRelation", kategorieId, objektKategorieId, True) ' Beispieldaten erzeugen bereichTable.Rows.Add(1, "1. Bereich", True) bereichTable.Rows.Add(2, "2. Bereich", False) ' nicht aktiv bereichTable.Rows.Add(3, "3. Bereich", True) kategorieTable.Rows.Add(10, "Kategorie 10", 1, True) kategorieTable.Rows.Add(11, "Kategorie 11", 1, False) ' nicht aktiv kategorieTable.Rows.Add(12, "Kategorie 12", 1, True) kategorieTable.Rows.Add(20, "Kategorie 20", 2, True) kategorieTable.Rows.Add(21, "Kategorie 21", 2, False) kategorieTable.Rows.Add(30, "Kategorie 30", 3, True) kategorieTable.Rows.Add(31, "Kategorie 31", 3, True) kategorieTable.Rows.Add(32, "Kategorie 32", 3, True) objektTable.Rows.Add(101, "Nr 101", "Objekt 101", 10, 1) objektTable.Rows.Add(102, "Nr 102", "Objekt 102", 10, 1) objektTable.Rows.Add(111, "Nr 111", "Objekt 111", 11, 1) objektTable.Rows.Add(121, "Nr 121", "Objekt 121", 12, 1) objektTable.Rows.Add(301, "Nr 301", "Objekt 301", 30, 1) objektTable.Rows.Add(311, "Nr 311", "Objekt 311", 31, 1) objektTable.Rows.Add(321, "Nr 311", "Objekt 321", 32, 1) Return dataSet End Function #End Region End Class
Nachhaken, falls Unklarheiten bestehen.
Gruß Elmar
- Als Antwort markiert mjanz Donnerstag, 9. September 2010 13:31
-
Hallo Elmar,
also ich muss hier mal eine Lobeshymne singen. Nach der Lektüre Deiner Links und des Codes konnte ich genau das Nachstellen, was ich wollte. Ich habe zwar noch das ein oder andere selber zwischengefummelt, um noch ein paar Kleinigkeiten dazu zu bekommen, aber als ich verstanden hatte wie es ging, lief das problemlos. Tausend Dank nochmal!
LG
Marcus
Der erste Tag, an dem ich nichts Neues lerne, wird der Tag sein, an dem sich der Deckel über mir schließt...