Home > Artikel > Ausgabe 8/2013 > Das TreeView-Steuerelement: Grundlagen, Teil II

Das TreeView-Steuerelement: Grundlagen, Teil II

Achtung: Sie sind nicht angemeldet. Wenn Sie Abonnent sind und sich anmelden, lesen Sie den kompletten Artikel, laden das PDF herunter oder probieren die Beispieldatenbank aus (sofern vorhanden).

Das TreeView-Steuerelement ist der Alleskönner zur Anzeige hierarchischer Daten. Sie zeigen damit sowohl die Daten aus Tabellen mit reflexiver Verknüpfung an als auch Daten, die aus verschiedenen verknüpften Tabellen stammen – wie etwa Kunden und Projekte. Das Steuerelement kann als ActiveX-Steuerelement im Gegensatz zu den eingebauten Steuerelementen von Access nicht direkt an eine Datenherkunft gebunden werden, also ist ein wenig Handarbeit nötig, um dieses zu füllen. In dieser Artikelreihe lernen Sie die Grundlagen zu diesem Steuerelement kennen und erfahren, wie Sie es mit Daten füllen.

Beispieldatenbank

Die Beispiele dieses Artikels finden Sie in der Datenbank 1308_TreeView.mdb.

TreeView-Verlust vorbeugen

Gerade während der Entwicklung und beim Experimentieren mit den Möglichkeiten des TreeViews treten des öfteren Fehler auf. Wird ein Fehler nicht behandelt, führt dies dazu, dass Objektvariablen wie obj­TreeView zurückgesetzt und somit geleert werden.

Das bedeutet, das erstens keine für dieses Steuerelement programmierten Ereignisse mehr ausgelöst werden und dann der Zugriff per Code auf die entsprechende Objektvariable wiederum zu Fehlern führt.

Es gibt jedoch eine Möglichkeit, diese Variable bei Bedarf immer wieder neu mit einem Verweis auf das TreeView-Steuerelement zu füllen.

Dazu deklarieren Sie die Variable zum Speichern des Verweises ähnlich wie zuvor, diesmal allerdings unter einem anderen Namen – nämlich m_TreeView. Der Grund ist, dass wir den zuvor verwendeten Namen objTreeView als Name einer Property Get-Prozedur verwenden. Genaueres über solche Prozeduren erfahren Sie in einem späteren Artikel über die Klassenprogrammierung unter VBA – fürs erste reicht es, wenn Sie wissen, dass die Property Get-Prozedur ähnlich wie eine Funktion einen Wert oder einen Verweis zurückliefert.

In diesem Fall prüft diese Prozedur, ob die Variable m_TreeView bereits gefüllt ist, und zwar durch den Is-Vergleich mit dem Ausdruck Nothing. Ist dies wahr, wurde die Variable entweder noch nicht befüllt oder ist durch einen Fehler wieder geleert worden.

In beiden Fällen soll diese jedoch gefüllt werden. Der Inhalt der Variablen wird dann, unabhängig davon, ob er erst jetzt gefüllt wurde oder bereits gefüllt war, mit der Property Get-Prozedur objTreeView zurückgegeben (siehe Listing 1).

Dim WithEvents m_Treeview As MSComctlLib.TreeView

Private Property Get objTreeView() As MSComctlLib.TreeView

     If m_Treeview Is Nothing Then

         Set m_Treeview = Me!ctlTreeView.Object

     End If

     Set objTreeView = m_Treeview

End Property

Listing 1: objTreeView liefert immer einen Verweis auf das TreeView-Steuerelement in ctlTreeView.

objTreeView muss auf diese Weise nicht mehr in der Form_Load-Ereignisprozedur gefüllt werden.

Dieses Beispiel finden Sie im Formular frmTreeView_mTreeView.

TreeView-Eigenschaften per Code einstellen

Wenn Sie hier und da TreeView-Steurelemente einbauen, möchten Sie vielleicht gern die Eigenschaften wie bei einem TreeView-Steuerelement einstellen, mit denen bereits gute Erfahrungen in einer anderen Anwendung gemacht haben.

In meinen Anwendungen verzichte ich daher völlig auf die Einstellung der Eigenschaften über den entsprechenden Dialog des TreeView-Steuerelements im Formularentwurf. Ich stelle die Eigenschaften immer gleich beim Laden des Formulars per VBA-Code ein. Für einige Standardeigenschaften, die sich auf das Aussehen des TreeView-Steuerelements beziehen, sieht dies etwa wie folgt aus:

Private Sub Form_Load()

     With objTreeView

         .Appearance = ccFlat

         .BorderStyle = ccNone

         .LineStyle = tvwRootLines

         .Style = µ

             tvwTreelinesPlusMinusText

     End With

End Sub

In den folgenden Beispielen kommen je nach Bedarf noch weitere Eigenschaften hinzu. Wenn Sie diese Eigenschaften für TreeView-Steuerelemente in andere Formulare oder gar andere Anwendungen übernehmen möchten, kopieren Sie einfach die entsprechenden Codezeilen in die Form_Load-Prozedur.

TreeView füllen

Nun haben wir die Voraussetzungen dafür geschaffen, dass TreeView-Steuerelement per VBA mit den gewünschten Werten zu füllen.

Das TreeView-Steuerelement besitzt eine Auflistung namens Nodes, die alle im TreeView-Steuerelement angezeigten Element aufnimmt. Ein einzelnes Element im TreeView heißt dementsprechend Node. Um ein Node-Objekt zum TreeView hinzuzufügen, verwenden Sie die Add-Methode der Nodes-Auflistung.

Wenn Sie einen Node zur obersten Ebene der Hierarchie im TreeView-Steuerelement einfügen möchten, sieht der Aufruf etwa wie in Listing 2 aus. Das Element wird hier bei Laden des Formulars hinzugefügt (siehe Bild 1).

Erstes Element im TreeView-Steuerelement

Bild 1: Erstes Element im TreeView-Steuerelement

Die Add-Methode erwartet die folgenden Parameter:

  • Relative: Gibt den Key-Wert eines Elements an, zu dem das neue Element in Beziehung stehen soll.
  • Relationship: Gibt die Beziehung des neuen Elements zu dem in Relative bezeichneten Element an. Die Werte sind tvwChild, tvwFirst, tvwLast, tvwNext, tvwPrevious.
  • Key: Ein eindeutiger Schlüssel für jedes Element, der mit einem Buchstaben beginnen muss.
  • Text: Der durch das Element angezeigte Text.
  • Image: Name eines Bildes, das als Icon des Elements angezeigt werden soll.
  • SelectedImage: Name eines Bildes, dass statt des in Image festgelegten Bildes angezeigt werden soll, wenn das Element ausgewählt ist.

Zum Anlegen eines ersten Elements reichen die beiden Parameter Key und Text aus.

Zu den Eigenschaften Image und SelectedImage kommen wir in einem späteren Teil der Artikelreihe.

Da es etwas müßig ist, das Formular zum Ausprobieren des Codes nach jeder Änderung immer wieder neu zu schließen und zu öffnen, fügen wir diesem eine Schaltfläche hinzu, das die Prozedur zum Füllen des TreeView-Steuerelements auslöst.

Für die folgenden Beispiele erweitern wir das Formular dann entsprechend um weitere Schaltflächen.

Die erste aus Bild 2 löst somit folgende Prozedur aus:

Erstes Element per Schaltfläche

Bild 2: Erstes Element per Schaltfläche

Private Sub cmdErstesElement_Click()

     objTreeView.Nodes.Add , , "a1", "Erster Knoten"

End Sub

TreeView leeren

Wenn einem TreeView mehrfach die gleichen Elemente hinzufügen möchten, müssen Sie die vorhandenen Elemente zuvor entfernen.

Anderenfalls tritt ein Fehler auf, sobald Sie ein Element hinzufügen, dessen Key-Wert bereits einem der anderen Elemente im TreeView-Steuerelement zugeordnet ist. Es ist allerdings kein Problem, die vorhandenen Elemente zu löschen – dazu verwenden Sie einfach die Clear-Anweisung der Nodes-Auflistung:

objTreeView.Nodes.Clear

Weitere Elemente in der obersten Ebene

Um der obersten Ebene weitere Elemente hinzuzufügen, rufen Sie einfach die Add-Methode mit den gewünschten Key- und Name-Werten auf – also beispielsweise so:

objTreeView.Nodes.Add , , "a1", "Erster Knoten"

objTreeView.Nodes.Add , , "a2", "Zweiter Knoten"

objTreeView.Nodes.Add , , "a3", "Dritter Knoten"

Die Elemente werden dann genau in dieser Reihenfolge angelegt.

Verwandte Elemente anlegen

Wenn Sie weitere Elemente anlegen und dabei deren Position einstellen möchten, verwenden Sie die beiden Parameter Relative und Relationship. Der am häufigsten eingesetzte Fall dürfte das Einfügen eines Kindelements sein. Die Prozedur aus Listing 3 legt einige Eltern- und Kindelemente an.

Private Sub cmdRelativeWerte_Click()

     objTreeView.Nodes.Clear

     objTreeView.Nodes.Add , , "a1", "Erster Knoten"

     objTreeView.Nodes.Add "a1", tvwChild, "a11", "Erster Kind-Knoten"

     objTreeView.Nodes.Add , , "a2", "Zweiter Knoten"

     objTreeView.Nodes.Add "a2", tvwChild, "a21", "Zweiter Kind-Knoten"

     objTreeView.Nodes.Add "a2", tvwChild, "a22", "Dritter Kind-Knoten"

End Sub

Listing 3: Hinzufügen zweier Elemente und einiger Kindelemente

Das Ergebnis finden Sie in Bild 3.

Eltern- und Kindelemente

Bild 3: Eltern- und Kindelemente

Dies ist der Normalfall: Die Elemente werden gleich in der gewünschten Reihenfolge angelegt, die beispielsweise durch die Sortierung der zugrunde liegenden Daten vorgegeben wird. Gleiches gilt für das Hinzufügen der untergeordneten Elemente.

Es kann jedoch auch geschehen, dass Sie nachträglich ein Element vor oder hinter ein bestimmtes Element oder an erster oder letzter Stelle der Ebene eines bestimmten Elements einfügen möchten.

Dann kommen neben tvwChild weitere Konstanten für den Parameter Relationship zum Tragen. Die Prozedur aus Listing 4 ist die erweiterte Version der zuvor beschriebenen Prozedur. Zu den bereits vorhandenen Elementen fügt die Prozedur die folgenden Elemente hinzu:

Private Sub cmdRelativeWerteII_Click()

     ....

     objTreeView.Nodes.Add "a1", tvwFirst, "a3", "Als Erster eingeschoben"

     objTreeView.Nodes.Add "a11", tvwLast, "a12", "Als Letzter eingeschoben"

     objTreeView.Nodes.Add "a21", tvwNext, "a12a", "Nach Element eingeschoben"

     objTreeView.Nodes.Add "a22", tvwPrevious, "a12b", "Vor Element eingeschoben"

End Sub

Listing 4: Hinzufügen von Elementen als erstes, letztes, folgendes und vorheriges Element einer Ebene

  • das Element a3 als erstes Element der Ebene, in der sich das Element a1 befindet,
  • das Element a12 als letztes Element der Ebene des Elements a11,
  • das Element a21a als folgendes Element des Elements a21 und
  • das Element a21b als vorheriges Element des Elements a22.

Das Ergebnis finden Sie in Bild 4.

Nachträgliches Einfügen von Elementen in Abhängingkeit anderer Elemente

Bild 4: Nachträgliches Einfügen von Elementen in Abhängingkeit anderer Elemente

Elemente beim Anlegen ausklappen

Wenn ein Element noch untergeordnete Elemente besitzt, sollen diese möglicherweise gleich angezeigt werden. Standardmäßig werden die Zweige jedoch nicht aufgeklappt. Dies können Sie allerdings nachholen – und zwar, indem Sie die Eigenschaft Expanded des jeweiligen übergeordneten Elements auf True einstellen. Das gelingt am einfachsten, wenn Sie das Node-Element direkt beim Erstellen einer passenden Objektvariablen zuweisen – mehr dazu weiter unten.

Verweis mit Objektvariable

Wenn Sie einmal einen Verweis auf eines der Elemente des TreeView-Steuerelements in einer Variablen speichern wollen, deklarieren Sie zunächst eine entsprechende Variable des Typs Node – zum Beispiel mit dem Namen objNode. Diese füllen Sie dann mit der Set-Anweisung mit dem Verweis auf das entsprechende Element. Der Ausdruck objTreeView.SelectedItem liefert beispielsweise einen Verweis auf das aktuell markierte Element. Die Prozedur aus Listing 5 zeigt, wie ein Element referenziert wird und wie Sie anschließend über die Objektvariable auf die Eigenschaften des Node-Elements zugreifen.

Private Sub cmdAktuellesElement_Click()

     Dim objNode As MSComctlLib.Node

     Set objNode = objTreeView.SelectedItem

     Debug.Print objNode.Key, objNode.Text

End Sub

Listing 5: Speichern eines Verweises auf ein Element in einer Variablen

Ein weiterer guter Anlass, die Elemente jeweils in einer Node-Variablen zu speichern, ist das anschließende Zuweisen von Eigenschaften an ein Element. Sie brauchen dann nicht für jede Eigenschaft den kompletten Ausdruck zu verwenden, sondern können die Eigenschaften über die Objektvariable zuweisen. Im Beispiel aus Listing 6 stellt die Prozedur zum Beispiel für alle hinzugefügten Elemente gleich die Eigenschaft Expanded auf den Wert True ein, damit alle Äste ausgeklappt werden.

Private Sub cmdAlleAusklappen_Click()

     Dim objNode As MSComctlLib.Node

     objTreeView.Nodes.Clear

     Set objNode = objTreeView.Nodes.Add(, , "a1", "Erster Knoten")

     objNode.Expanded = True

     Set objNode = objTreeView.Nodes.Add("a1", tvwChild, "a11", "Erster Kind-Knoten")

     objNode.Expanded = True

     ...

End Sub

Listing 6: Referenzieren von Node-Objekten und anschließende Einstellung von Variablen

Anzahl der Elemente ermitteln

Sie haben das Ende des frei verfügbaren Teil dieses Artikels erreicht!

Wenn Sie mehr lesen und auf viele weitere Artikel zugreifen möchten, melden Sie sich als Abonnent unter Login an. Falls nicht, bestellen Sie doch einfach ein Jahresabonnement!