ListView-Konfigurator

Das ListView-Steuerelement bietet einige interessante Features, die Sie in der Datenblattansicht und im Listenfeld nicht finden. Allein das Bestücken mit Daten ist ein wenig mühselig – das ListView-Steuerelement kann nicht wie das Listenfeld oder ein Unterformular in der Datenblattansicht einfach an eine Datenherkunft gebunden werden. Diese und einige andere Schwächen behebt die vorliegende Lösung – der ListView-Konfigurator.

ListView-Konfigurator im Einsatz

Der ListView-Konfigurator ist eine Klasse, mit der Sie ein ListView-Steuerelement programmieren können – allerdings etwas umfangreicher und einfacher, als dies mit dem herkömmlichen Funktionsumfang dieses Steuerelements möglich ist. Um den ListView-Konfigurator einzusetzen, gehen Sie wie folgt vor:

  • Fügen Sie ein ListView-Steuerelement zum gewünschten Formular hinzu und nennen Sie es ctlListView.
  • Importieren Sie die Klasse clsListViewConf in die Datenbank, in der sich auch das Formular befindet. Sie finden die Klasse in der Beispieldatenbank zu diesem Beitrag.
  • Deklarieren Sie eine Objektvariable für diese Klasse:
Dim WithEvents objListViewConf As clsListViewConf
  • Legen Sie eine Prozedur für das Ereignis Beim Laden des Formulars an. Dieses statten Sie zunächst mit der Instanzierung der Klasse aus. Außerdem weisen Sie der Eigenschaft ListView der Instanz einen Verweis auf das betroffene Steuerelement zu:
Private Sub Form_Load()
    Set objListViewConf = New clsListViewConf
    With objListViewConf
        Set .ListView = Me!ctlListView.Object
        ... weitere Befehle
    End With
End Sub

Danach nehmen Sie weitere Einstellungen vor, die wir nun vorstellen. Zunächst folgen einige allgemeine Eigenschaften, die Sie auch für herkömmliche Listenfelder vornehmen können:

.Appearance = ccFlat
.BorderStyle = ccNone
.View = lvwReport
.Font.Name = "Calibri"
.Font.Size = 10

Dies führt nach dem Füllen des ListView-Steuerelements, das wir später mit der Fill-Methode der Klasse clsListViewConf durchführen, zu einer Ansicht wie in Bild 1. Alle folgenden Beispiele zielen auf eine solche datenblattartige Ansicht ab; die Darstellung von Icons, Bildern et cetera in anderen Ansichten wird nicht optimal unterstützt.

pic002.png

Bild 1: Einfache ListView-Ansicht

Um diese Ansicht zu erhalten, brauchen Sie zu den obigen Anweisungen nur noch zwei weitere Codezeilen hinzuzufügen:

.RowSource = "qryArtikel_ListView"
.Fill

Die neue Eigenschaft RowSource nimmt den Namen einer Tabelle oder Abfrage oder auch einen SQL-Ausdruck an. Die Fill-Methode schließlich liest die Werte dieser Datenherkunft aus und schreibt sie wie in der Abbildung in das ListView-Steuerelement. Eine weitere Voraussetzung ist eine entsprechend vorbereitete Datenherkunft. In diesem Fall sieht die Abfrage qryArtikel_ListView wie in Bild 2 aus.

pic003.png

Bild 2: Beispiel für eine Datenherkunft für das ListView-Steuerelement

Hier sind zwei Dinge zu beachten: Erstens wurde das Primärschlüsselfeld nach hinten geschoben, da die Felder in der Reihenfolge wie in der Datenherkunft eingelesen und angezeigt werden. Auf diese Weise steht der Artikelname ganz vorn und kann gegebenenfalls manuell im Listenfeld bearbeitet werden. Zweitens wurden Fremdschlüsselfelder durch die Felder der entsprechenden verknüpften Tabellen ersetzt, also Firma statt LieferantID und Kategoriename statt KategorieID.

Nur die ersten n Felder anzeigen

Die Datenherkunft muss also bereits die anzuzeigenden Felder in der richtigen Reihenfolge enthalten. Felder, die nicht angezeigt werden sollen, aber dennoch eine Funktion erfüllen – also etwa das Primärschlüsselfeld -, landen hinten. Und damit kommen wir zur ersten zusätzlichen Eigenschaft des ListView-Konfigurators. Die Eigenschaft heißt NumberOfVisibleFields und nimmt die Anzahl der anzuzeigenden Felder entgegen. Sie stellen diese wie folgt ein – hier auf die ersten vier Felder:

objListViewConf.NumberOfVisibleFields = 4

Das Formular frmListViewTest_ErsteN zeigt das Ergebnis (s. Bild 3).

pic005.png

Bild 4: ListView mit optimaler Spaltenbreite

Feldname oder Beschriftung

Die Fill-Methode untersucht automatisch, ob für das Feld einer Tabelle oder einer Abfrage eine Beschriftung angegeben wurde. Ist dies der Fall, wird die Beschriftung statt des Feldnamens als Spaltenüberschrift verwendet.

Optimale Spaltenbreite

Hier tritt gleich ein Problem auf, das auch von Listenfeldern und Datenblättern bekannt ist: Die Spalten werden nicht in der optimalen Breite angezeigt. Das Problem lösen Sie mit dem ListView-Konfigurator ganz einfach, indem Sie die Eigenschaft OptimizeColumnWidths auf den Wert True einstellen. Ein Beispiel hierfür finden Sie im Formular frmListViewTest_OptimaleBreite (s. Bild 4).

pic004.png

Bild 3: ListView-Steuerelement mit den ersten vier Feldern der Datenherkunft

Wert der ersten Spalte anpassen

Wenn Sie die eingebaute Eigenschaft LabelEdit auf den Wert lvwAutomatic einstellen, können Sie den Wert der ersten Spalte eines Listeneintrags im Bearbeitungsmodus darstellen und diesen ändern. Das Problem ist, dass die änderung nicht auf die zugrunde liegende Tabelle übertragen wird, da das ListView-Steuerelement ja normalerweise nicht an eine Datenherkunft gebunden ist. Dies ändert der ListView-Konfigurator. Er fügt einige weitere Eigenschaften hinzu, die das ändern des Wertes dieser einen Spalte erlauben. Dazu benötigen Sie drei Eigenschaften:

  • SaveLabelEdits: Legt mit dem Wert True fest, dass änderungen an der ersten angezeigten Spalte direkt nach der änderung in die zugrunde liegende Tabelle übertragen werden.
  • PrimaryKey: Legt fest, welches Feld der Datenherkunft das Primärschlüsselfeld ist.
  • BaseTable: Legt fest, aus welcher Tabelle Primärschlüsselfeld und zu änderndes Feld stammen. Beide müssen zur gleichen Tabelle gehören.

Erst die beiden Eigenschaften PrimaryKey und BaseTable erlauben es, die Tabelle und den Datensatz zu finden, in welche die vorgenommene änderung übertragen werden soll. Die Konfiguration sieht nun wie folgt aus:

Private Sub Form_Load()
    Set objListViewConf = New clsListViewConf
    With objListViewConf
        Set .ListView = Me!ctlListView.Object
        .Appearance = ccFlat
        .BorderStyle = ccNone
        .View = lvwReport
        .FullRowSelect = True
        .Font.Name = "Calibri"
        .Font.Size = 10
        .LabelEdit = lvwAutomatic
        .RowSource = "qryArtikel_ListView"
        .NumberOfVisibleFields = 4
        .PrimaryKey = "ArtikelID"
        .BaseTable = "tblArtikel"
        .OptimizeColumnWidths = True
        .SaveLabelEdits = True
        .Fill
    End With
End Sub

Bild 5 zeigt das Formular frmListViewTest_Anpassbar mit einem Feld, das gerade bearbeitet wird.

pic006.png

Bild 5: ändern der ersten Spalte eines Listenfeldeintrags

Kontrollkästchen anzeigen und speichern

Eines der interessanten Features von ListViews ist die Möglichkeit, in der ersten Spalte ein Kontrollkästchen anzuzeigen und mit beliebigen Daten zu füllen. Mit ein paar Zeilen Code können änderungen daran in der zugrunde liegenden Tabelle gespeichert werden. Die Klasse clsListViewConf bietet vier Eigenschaften an, mit denen Sie Kontrollkästchen anzeigen, füllen und änderungen in die zugrunde liegende Tabelle schreiben können:

  • Checkboxes ist eine Boolean-Eigenschaft, die bei der Einstellung True ein Kontrollkästchen in der ersten Spalte einblendet. Allein mit dieser eingebauten Eigenschaft geschieht nichts weiter – es werden keine Kontrollkästchen mit dem Wert True vorbelegt und auch keine änderungen gespeichert.
  • CheckBoxField: Diese Eigenschaft erwartet den Namen eines Boolean-Feldes, das den Wert für das Kontrollkästchen liefert. Im Beispiel haben wir dafür das Feld Auslaufartikel angegeben. Dementsprechend wird das Kontrollkästchen für alle Auslaufartikel aktiviert (s. Bild 6).
  • pic007.png

    Bild 6: Automatisch gefüllte Kontrollkästchen

  • CheckboxInOwnColumn: Normalerweise wird das Kontrollkästchen gemeinsam mit dem entsprechenden Wert mit in der ersten Spalte angezeigt. Dies können Sie ändern, indem Sie die Eigenschaft CheckboxInOwnColumn auf den Wert True einstellen. In diesem Fall wird eine eigene Spalte für die Kontrollkästchen angelegt.
  • CheckboxUpdate: Diese Eigenschaft stellen Sie auf True ein, wenn änderungen an den Kontrollkästchen direkt in das entsprechende Feld der Datenherkunft des ListView-Steuerelements übertragen werden sollen. Diese Funktion berücksichtigt das für CheckboxField angegebene Feld und benötigt auch die Angabe der beiden Eigenschaften PrimaryKey und BaseTable.

Eine Beispielkonfiguration könnte so aussehen:

.Checkboxes = True
.CheckboxField = "Auslaufartikel"
.CheckboxInOwnColumn = True
.CheckboxUpdate = True

Es spielt keine Rolle, ob das Kontrollkästchen in einer eigenen Spalte oder gemeinsam mit dem Wert der eigentlichen ersten Spalte angezeigt wird. Bild 7 zeigt den Unterschied zwischen ListView-Steuerelementen ohne Kontrollkästchen, mit Kontrollkästchen mit Text in der ersten Spalte und mit Kontrollkästchen in einer eigenen Spalte.

pic009.png

Bild 7: Checkbox-Varianten

Erweiterte Programmiermöglichkeiten

Durch das Wrappen der kompletten ListView-Klasse mit der Klasse clsListViewConf können auch Ereignisse hinzugefügt werden. Manchmal fehlt beispielsweise ein einfaches Ereignis, das beim Doppelklick den Primärschlüsselwert des angeklickten Elements liefert. Bild 8 zeigt, wie Sie das neue Ereignis ItemDoubleClick aus der Liste der Ereignisprozeduren für das Objekt objListViewConf auswählen können. Wenn Sie die Ereignisprozedur wie folgt ergänzen, zeigt das ListView-Steuerelement beim Doppelklick auf einen Eintrag den Primärschlüsselwert des jeweiligen Eintrags an – vorausgesetzt, Sie haben die Eigenschaft PrimaryKey auf das Primärschlüsselfeld der Datenherkunft eingestellt.

pic008.png

Bild 8: Hinzufügen neuer Ereignisse

ListView-Konfigurator im Eigenbau

Sie haben nun die Möglichkeiten des ListView-Konfigurators kennengelernt. Damit Sie den ListView-Konfigurator selbst erweitern können, zeigen wir auf den nächsten Seiten, wie dieser funktioniert. Der ListView-Konfigurator soll zunächst das Zuweisen einer Datenherkunft wie einer Tabelle, einer Abfrage oder auch einer SQL-SELECT-Anweisung ermöglichen. Um dies zu erledigen, brauchen Sie zumindest eine Prozedur, der Sie einen Verweis auf das betroffene ListView-Steuerelement zuweisen und dem Sie die zu verwendende Datenherkunft mitteilen. Das allein reicht jedoch nicht aus: In zusätzlichen Schritten müssen Sie festlegen, welche Felder der Datenherkunft angezeigt werden, ob ein Kontrollkästchen dargestellt werden soll und an welches Feld dieses gebunden wird und so weiter. Das ist ein wenig viel für eine einfache Prozedur mit einigen Parametern: Eine Klasse muss her, und diese soll sowohl die vorhandenen Eigenschaften, Methoden und Ereignisse des ListView-Steuerelements abbilden als auch die gewünschten neuen Möglichkeiten anbieten.

ListView-Klasse wrappen

Also beginnen wir, indem wir eine neue Klasse namens clsListViewConf erstellen, die alle Eigenschaften, Methoden und Ereignisse des echten ListView-Steuerelements abbildet. Dies ist teilweise eine echte Sisyphus-Arbeit, aber kein Problem für Sie: Sie können ja die Klasse der Beispieldatenbank in eigene Projekte übernehmen. An dieser Stelle sollen Sie jedoch trotzdem erfahren, wie die Basisfunktionen des ListView-Steuerelements abgebildet wurden. Nachdem die Klasse dann fertiggestellt ist, fügen wir dieser weitere Eigenschaften wie etwa die zum Zuweisen der Datenherkunft hinzu – und die dahinter stehende Funktionalität sorgt dann dafür, dass die entsprechenden Daten auch im ListView-Steuerelement angezeigt werden.

Die nachfolgenden Schritte sind nötig, damit Sie nur eine Klasse benötigen, um auf die Funktionen des ListView-Steuerelements zuzugreifen. Sie sollen ja nicht nur die neuen, hinzugefügten Funktionen nutzen, sondern auch die vorhandenen Features.

Eigenschaften abbilden

Wenn Sie Eigenschaften für ein ListView-Steuerelement per VBA einstellen, referenzieren Sie dieses zunächst und stellen dann die Eigenschaften ein. Im folgenden Beispiel geschieht das beispielsweise für die Eigenschaft Checkboxes, die angibt, ob für jeden Eintrag ein Kontrollkästchen angezeigt werden soll:

Dim objListView As MSComctlLib.ListView
Set objListView = Me!ctlListView.Object
With objListView
    .Checkboxes = True
End With

Dies bekommen Sie natürlich auch über den entsprechenden Eigenschaften-Dialog des Steuerelements hin (s. Bild 9).

pic001.png

Bild 9: Eigenschaften-Dialog eines ListView-Steuerelements

Wenn Sie jedoch einmal ein ListView-Steuerelement samt Konfiguration in ein anderes Formular oder auch in eine andere Anwendung übernehmen möchten, nehmen Sie die Einstellungen per VBA vor – Sie brauchen dann nur ein neues ListView-Steuerelement anzulegen und diesem mit den kopierten VBA-Anweisungen zur Laufzeit die Eigenschaften zuzuweisen. Natürlich können Sie unter VBA auch direkt über eine Referenz auf das Steuerelement zugreifen und Eigenschaften einstellen:

Me!ctlListView.Checkboxes = True

Nachteil: Diese Eigenschaften werden nicht per IntelliSense angezeigt. Um also später alle Eigenschaften des ListView-Steuerelements auch über unsere neue Klasse nutzen zu können, müssen wir diese wrappen. Das bedeutet, dass wir in der Klasse zunächst eine Objektvariable anlegen, die einen Verweis auf das ListView-Steuerelement aufnimmt:

Private WithEvents m_ListView As MSComctlLib.ListView

Um dieser Objektvariablen einen Verweis auf das ListView-Steuerelement zuweisen zu können, legen Sie die folgende Property Set-Anweisung an:

Public Property Set ListView(objListView As MSComctlLib.ListView)
    Set m_ListView = objListView
End Property

Wenn Sie die Klasse unter dem Namen clsListViewConf speichern, deklarieren Sie in einem Formular eine Objektvariable wie die folgende, um eine Instanz der Klasse aufzunehmen:

Dim WithEvents objListViewConf As clsListViewConf

In der Prozedur Form_Load weisen Sie diese dann zu:

Private Sub Form_Load()
    Set objListViewConf = New clsListViewConf
    With objListViewConf
        Set .ListView = Me!ctlListView.Object
    End With
End Sub

Nun zu den Eigenschaften: Um die oben bereits erwähnte Eigenschaft Checkboxes abzubilden, brauchen Sie eine Property Let-Prozedur, mit der Sie den Wert der Eigenschaft von außen einstellen können, und eine Property Get-Prozedur, mit der Sie den aktuellen Wert auslesen können.

Die Property Let-Prozedur fragt den zu setzenden Wert ab und stellt diesen direkt für die aktuelle Instanz des ListView-Steuerelements ein:

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar