Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
1 Einführung
2 Grundlagen der Sprachsyntax
3 Klassendesign
4 Weitere Datentypen
5 Multithreading
6 Collections und LINQ
7 Eingabe und Ausgabe
8 Anwendungen: Struktur und Installation
9 Code erstellen und debuggen
10 Einige Basisklassen
11 Windows-Anwendungen erstellen
12 Die wichtigsten Steuerelemente
13 Tastatur- und Mausereignisse
14 MDI-Anwendungen
15 Grafiken mit GDI+
16 Drucken
17 Entwickeln von Steuerelementen
18 Programmiertechniken
19 WPF – Grundlagen
20 Layoutcontainer
21 WPF-Steuerelemente
22 Konzepte von WPF
23 Datenbankverbindung mit ADO.NET
24 Datenbankabfragen mit ADO.NET
25 DataAdapter
26 Offline mit DataSet
27 Datenbanken aktualisieren
28 Stark typisierte DataSets
A Anhang: Einige Übersichten
Stichwort

Jetzt Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Visual Basic 2008 von Andreas Kuehnel, Stephan Leibbrandt
Das umfassende Handbuch
Buch: Visual Basic 2008

Visual Basic 2008
3., aktualisierte und erweiterte Auflage, geb., mit DVD
1.323 S., 49,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1171-0
Pfeil 12 Die wichtigsten Steuerelemente
Pfeil 12.1 Gemeinsamkeiten
Pfeil 12.1.1 Größe und Position
Pfeil 12.1.2 Sichtbarkeit und Aktivierungszustand
Pfeil 12.1.3 Beschriftung
Pfeil 12.1.4 Farben
Pfeil 12.1.5 Grafische Darstellung
Pfeil 12.1.6 Zugriffsrechte
Pfeil 12.1.7 Zusatzinformationen speichern
Pfeil 12.1.8 Position bei Größenänderung der Form
Pfeil 12.1.9 Die Größe mit der Form skalieren
Pfeil 12.1.10 Kindelemente
Pfeil 12.1.11 Steuerelemente fokussieren
Pfeil 12.1.12 Maus- und Tastaturereignisse
Pfeil 12.2 Schaltflächen (Button)
Pfeil 12.2.1 Rahmendarstellung
Pfeil 12.2.2 Beschriftung und Grafiken
Pfeil 12.3 Auswahlkästchen (CheckBox)
Pfeil 12.3.1 Eigenschaften
Pfeil 12.3.2 Drei Zustände
Pfeil 12.4 Gruppierung (GroupBox)
Pfeil 12.5 Optionsschaltflächen (RadioButton)
Pfeil 12.5.1 Gruppierung
Pfeil 12.5.2 Eigenschaften
Pfeil 12.5.3 Zustandswechsel programmieren
Pfeil 12.6 Texteingabefelder (TextBox)
Pfeil 12.6.1 Einzeilige Eingabefelder
Pfeil 12.6.2 Mehrzeilige Eingabefelder
Pfeil 12.7 Beschriftungen (Label)
Pfeil 12.8 Popuptextfenster (ToolTip)
Pfeil 12.8.1 Definition von Hinweistexten
Pfeil 12.8.2 Anzeigedauer der Texte
Pfeil 12.8.3 Weitere Eigenschaften
Pfeil 12.9 Auswahllisten (ListBox)
Pfeil 12.9.1 Daten einer ListBox
Pfeil 12.9.2 Darstellung einer Listbox
Pfeil 12.9.3 Einfach- und Mehrfachauswahl
Pfeil 12.9.4 Listboxen mit Einfachauswahl
Pfeil 12.9.5 Listboxen mit Mehrfachauswahl
Pfeil 12.9.6 Benutzerdefinierte Sortierung
Pfeil 12.9.7 Auswahlliste mit Datenquelle (DataSource)
Pfeil 12.10 Markierte Auswahllisten (CheckedListBox)
Pfeil 12.11 Kombinationslistenfelder (ComboBox)
Pfeil 12.11.1 Ereignisse
Pfeil 12.11.2 Autovervollständigung
Pfeil 12.12 Standarddialoge
Pfeil 12.12.1 Datei zum Öffnen wählen (OpenFileDialog)
Pfeil 12.12.2 Datei zum Speichern wählen (SaveFileDialog)
Pfeil 12.12.3 Ordner selektieren (FolderBrowserDialog)
Pfeil 12.12.4 Farbe bekennen (ColorDialog)
Pfeil 12.12.5 Schriftart wählen (FontDialog)
Pfeil 12.13 Menüs, Symbol- und Statusleisten
Pfeil 12.13.1 Menüsammlung (ToolStripContainer)
Pfeil 12.13.2 Menüdefinition
Pfeil 12.13.3 Eigenschaften von Menüs
Pfeil 12.13.4 Kontextmenüs
Pfeil 12.13.5 Symbolleisten
Pfeil 12.13.6 Statusleisten
Pfeil 12.14 Bildlaufleisten (HScrollBar und VScrollBar)
Pfeil 12.15 Fortschrittsbalken (ProgressBar)
Pfeil 12.16 Animationen (Timer)
Pfeil 12.17 Container (Panel)
Pfeil 12.18 Registerkarten (TabControl)
Pfeil 12.19 Baumansichten (TreeView und TreeNode)
Pfeil 12.19.1 Knotenpunkte definieren
Pfeil 12.19.2 Eigenschaften
Pfeil 12.19.3 Ereignisse
Pfeil 12.19.4 Knotenexpansion und -reduktion
Pfeil 12.19.5 Knoten (TreeNode)
Pfeil 12.20 Teiler (Splitter und SplitContainer)
Pfeil 12.20.1 Splitter
Pfeil 12.20.2 SplitContainer
Pfeil 12.21 Listenansicht (ListView)
Pfeil 12.21.1 Beteiligte Klassen
Pfeil 12.21.2 Eigenschaften und Ereignisse
Pfeil 12.21.3 Listenelemente (ListViewItem)
Pfeil 12.21.4 Unterelemente in Spalten (ListViewSubItem)
Pfeil 12.21.5 Spaltenüberschriften (ColumnHeader)
Pfeil 12.21.6 Listenelemente Gruppen zuordnen
Pfeil 12.21.7 Sortierung der Spalten
Pfeil 12.21.8 Listenelemente ändern
Pfeil 12.21.9 Dateiexplorer-Beispiel


Rheinwerk Computing - Zum Seitenanfang

12.9 Auswahllisten (ListBox) Zur nächsten ÜberschriftZur vorigen Überschrift

Oft ist es erforderlich, dem Benutzer zur Laufzeit eine Auflistung von Elementen in Form von Zeichenfolgen anzubieten. Aus dieser Liste kann der Benutzer ein oder auch mehrere Elemente auswählen. .NET stellt zu diesem Zweck mehrere Steuerelemente zur Verfügung, von denen die drei wichtigsten

  • ListBox
  • CheckedListBox
  • ComboBox

sind. In diesem Abschnitt werden wir uns zunächst der Klasse ListBox widmen, die beiden anderen werden danach erläutert.


Rheinwerk Computing - Zum Seitenanfang

12.9.1 Daten einer ListBox Zur nächsten ÜberschriftZur vorigen Überschrift

Die von einer ListBox verwalteten Listeneinträge sind Elemente einer Auflistung vom Typ ListBox.ObjectCollection, auf die über die Eigenschaft Items zugegriffen werden kann. Wenn wir der Listbox ein Element hinzufügen wollen, ein bestimmtes Element aus ihr entfernen wollen oder nach einem bestimmten Element suchen, greifen wir auf die Methoden dieser Auflistung zurück.

Neue Listenelemente

Manchmal ist es möglich, eine ListBox bereits zur Entwicklungszeit vollständig zu füllen. Sie brauchen in diesem Fall im Eigenschaftsfenster nur die Eigenschaft Items zu markieren und können über die Schaltfläche in der Wertespalte einen Dialog öffnen, in dem Sie die Listenelemente der Reihe nach eintragen.

Meistens allerdings werden Sie Listen erst zur Laufzeit dynamisch füllen können, um sich unterschiedlichen Umgebungsbedingungen anzupassen. Als Mitglieder einer Collection werden Listenelemente über Indizes verwaltet. Das erste Listenelement hat, wie üblich, den Index 0. Drei Methoden ermöglichen es Ihnen, ein Element einer Listbox hinzuzufügen: Add, AddRange und Insert.

Betrachten wir zuerst die Add-Methode, deren Rückgabewert der Index ist, an dem das Element hinzugefügt worden ist. Das Element, das hinzugefügt werden soll, ist vom Typ Object und damit beliebig. Angezeigt wird der Rückgabewert der Methode ToString.

Im folgenden Codefragment werden mit der Add-Methode die drei Elemente Franz, Joseph und Uwe hinzugefügt.

Dim listBox1 As New ListBox(); 
listBox1.Items.Add("Franz") 
listBox1.Items.Add("Joseph") 
listBox1.Items.Add("Uwe")

Eine Alternative zum sich wiederholenden Add-Aufruf bietet die Methode AddRange, die ein Objekt-Array erwartet:

listBox1.Items.AddRange(New String() {"Franz", "Joseph", "Uwe"})

Soll ein neues Element nicht an das Ende angehängt werden, sondern eine bestimmte Position innerhalb aller Listenelemente einnehmen, verwenden Sie die Methode Insert. Dem ersten Parameter wird der gewünschte Index des hinzuzufügenden Elements übergeben, dem zweiten Parameter das Element. Die folgende Anweisung fügt Peter mit dem Index 1 an der zweiten Position der Listbox ein:

listBox1.Items.Insert(1, "Peter")

Wenn der Index größer ist als die Anzahl der Elemente in der Listbox, kommt es zu der Ausnahme ArgumentOutOfRangeException.

Listenelemente können mit Sorted auch alphabetisch sortiert werden. Sorted ist standardmäßig auf False eingestellt. Fügen Sie ein Element in eine sortierte Liste ein, wird das neue Element direkt einsortiert.

Hinzufügen vieler Listenelemente

Die Methode Add hat im Vergleich zur AddRange-Methode den Nachteil, dass die Listbox mit jedem hinzugefügten Listenelement neu aufgebaut wird. Handelt es sich um eine größere Elementanzahl, hat das einen spürbaren Leistungsverlust zur Folge. Besonders deutlich wird der Effekt in Kombination mit Sorted=True. Mit der Methode BeginUpdate lässt sich das Aktualisieren einer Listbox so lange unterdrücken, bis EndUpdate aufgerufen wird. Der Leistungsgewinn kann unter Umständen drastisch sein.

Die folgenden Anweisungen demonstrieren den Einsatz der beiden Methoden. Für die Dauer des Schleifendurchlaufs wird der Mauscursor als Sanduhr angezeigt, um zu signalisieren, dass die Anwendung eine länger andauernde Operation ausführt.

listBox1.Sorted = True 
listBox1.BeginUpdate() 
Me.Cursor = Cursors.WaitCursor 
For i As Integer = 0 To 999 
  listBox1.Items.Add(i) 
Next 
listBox1.EndUpdate() 
Me.Cursor = Cursors.Default

Den Effekt können Sie sehr gut beobachten, wenn Sie die Aufrufe von BeginUpdate und EndUpdate auskommentieren. Der Aufbau der Listbox benötigt dann ein Vielfaches der Zeit.

Löschen eines Elements

Jedes Element in einer Listbox kann durch den in der Listbox angezeigten Text und durch seinen Index beschrieben werden. Analog hat ListBox.ObjectCollection zwei Methoden, um ein bestimmtes Element aus der Auflistung zu entfernen: Remove und RemoveAt.

Remove erwartet als Argument die Referenz auf ein Objekt und wertet wiederum dessen ToString-Rückgabe aus; RemoveAt nimmt den Index entgegen. Wird ein Element mitten aus der Liste entfernt, verschieben sich alle Nachfolgeindizes, denn eine Auflistung kann niemals eine unbesetzte Position enthalten.

listBox1.Items.Remove("Joseph")

Clear löscht alle Listenelemente gleichzeitig.

Doppeleinträge vermeiden

Die Listenelemente einer Listbox sind nicht eindeutig – Sie können dasselbe Element auch mehrfach hinzufügen. Um das zu vermeiden, muss ein hinzuzufügendes Element zuerst daraufhin überprüft werden, ob es bereits eingetragen ist. Die Information darüber liefert die Methode Contains unter Angabe des Objekts. Der Rückgabewert ist vom Typ Boolean und True, wenn das im Parameter genannte Objekt in der Liste enthalten ist.

If Not listBox1.Items.Contains("Franz") Then listBox1.Items.Add("Franz")

Position eines Listenelements

Die Methode IndexOf() liefert die Position eines Elements in der Listbox.

Dim index As Integer = listBox1.Items.IndexOf("Marokko")

Ist das angegebene Element in der Liste nicht enthalten, ist der Rückgabewert -1.


Rheinwerk Computing - Zum Seitenanfang

12.9.2 Darstellung einer Listbox Zur nächsten ÜberschriftZur vorigen Überschrift

Jetzt wissen Sie, wie die Elemente einer Listbox in der speziellen Auflistung ListBox.ObjectCollection verwaltet werden. Wir können uns nun den Eigenschaften der ListBox zuwenden, die die Darstellung zur Laufzeit kontrollieren.

Die Höhe eines Steuerelements kann grundsätzlich beliebig eingestellt werden. Bei einer ListBox kann das dazu führen, dass ein Listenelement nur teilweise angezeigt wird. Mit der Eigenschaft IntegralHeight wird das vermieden. Diese Eigenschaft ist auf True voreingestellt und bewirkt, dass sich die Höhe der Listbox automatisch so anpasst, dass alle Elemente vollständig angezeigt werden.

Läuft die Liste über und können nicht alle Elemente gleichzeitig angezeigt werden, wird zur Laufzeit automatisch eine vertikale Bildlaufleiste eingeblendet. Insbesondere bei Listboxen, die zur Laufzeit dynamisch gefüllt werden, möchten Sie vielleicht auch dann eine Bildlaufleiste anzeigen, wenn die Anzahl der Listenelemente das Steuerelement noch nicht vollständig ausfüllt. Stellen Sie dazu die Eigenschaft ScrollAlwaysVisible=True ein. Überschreitet die Breite des Listeneintrags die Breite der Listbox, ist der nicht sichtbare Teil rechts abgeschnitten. In diesem Fall kann mit der Eigenschaft HorizontalScrollbar eine horizontale Bildlaufleiste angezeigt werden.

Mehrspaltige Listboxen

Unabhängig davon, wie viele Elemente in der Auflistung enthalten sind, ist eine Listbox zunächst immer nur einspaltig. In Abbildung 12.12 enthält die Listbox alle auf dem aktuellen System installierten Schriftarten, die über die Liste InstalledFontCollection im Namensraum System.Drawing.Text bereitgestellt werden. Um die Listbox beim Laden des Formulars zu füllen, eignet sich das Load-Ereignis oder der Konstruktor der Form:

Private Sub Fonts_Load(ByVal sender As Object, ByVal e As EventArgs) _ 
Handles MyBase.Load 
  Dim fonts As New System.Drawing.Text.InstalledFontCollection() 
  Dim familie As FontFamily() = fonts.Families 
  For Each f As FontFamily In familie 
    Art.Items.Add(f.Name) 
  Next 
  ...

End Sub

Die Eigenschaft Families eines InstalledFontCollection-Objekts liefert ein Array vom Typ FontFamily zurück. Dieser Typ definiert eine Schriftart und veröffentlicht die Eigenschaft Name, die den Bezeichner des Fonts liefert. In der Schleife werden die Namen aller Schriftarten mit der Add-Methode zur Items-Auflistung hinzugefügt.

Abbildung 12.12 Anzeige aller installierten Fonts in einer Listbox

Wenn Sie möchten, können Sie die Listenelemente auch auf mehrere Spalten aufteilen. Die Verteilung der Spalten erfolgt dabei so, dass keine vertikalen Bildlaufleisten mehr notwendig sind, sondern nur noch eine horizontale, die die Navigation zwischen den Spalten ermöglicht. Dazu muss die Eigenschaft MultiColumn=True gesetzt werden. Eine Listbox mit mehreren Spalten sehen Sie in Abbildung 12.13.

Abbildung 12.13 Mehrspaltige Anzeige in einer Listbox

Die Spaltenbreite können Sie mit ColumnWidth kontrollieren. Aber seien Sie hier vorsichtig. Wenn Sie nämlich eine zu geringe Breite wählen, wird der »überhängende« Teil von der Folgespalte überdeckt. Der Standardwert von 0 legt eine vordefinierte Breite fest, die allerdings nicht die Lesbarkeit aller Elemente sicherstellt.


Rheinwerk Computing - Zum Seitenanfang

12.9.3 Einfach- und Mehrfachauswahl Zur nächsten ÜberschriftZur vorigen Überschrift

Standardmäßig kann in einer Listbox zur Laufzeit nur ein Eintrag ausgewählt werden. Soll der Anwender gleichzeitig mehrere Einträge markieren können, legen Sie die Eigenschaft SelectionMode der Listbox entsprechend fest. Diese Eigenschaft bezieht ihre Werte aus der gleichnamigen Enumeration, die die vier Mitglieder in Tabelle 12.8 hat.


Tabelle 12.8 Die Enumeration »SelectionMode«

Konstante Selektion

None

Es kann kein Listenelement selektiert werden.

One

Nur ein Listenelement kann selektiert werden.

MultiSimple

Jede Auswahl eines Listenelements verändert die Selektion um genau ein Element.

MultiExtended

Durch Druck auf die Taste Strg -Taste oder die Umschalttaste ergänzen Sie eine Auswahl eines Listenelements um eine bereits vorhandene Selektion.


Bei der Einstellung MultiSimple kann der Anwender mittels Mausklick in beliebiger Reihenfolge die Elemente auswählen, die dann invertiert dargestellt werden. Zudem kann er mit den Pfeiltasten durch die Liste navigieren und mit der Leertaste das fokussierte Element selektieren. Ein Mausklick oder das Drücken der Leertaste auf ein ausgewähltes Element hebt die Markierung des Elements wieder auf.

Die Auswahl MultiExtended ist dann vorteilhaft, wenn der Anwender einen Bereich aufeinanderfolgender Elemente auswählen soll. Wird ein Element mit der Maus ausgewählt und danach die Umschalttaste gedrückt, sind nach dem Klick auf ein zweites Listenelement alle Elemente zwischen diesen beiden automatisch selektiert. Ähnlich kann auch die Auswahl mit der Tastatur erweitert werden, indem man die Umschalttaste beim Drücken der Pfeiltasten gedrückt hält. Bei gleichzeitigem Druck auf die Taste Strg -Taste kann die Selektion um genau ein Element verändert werden. So können auch nicht zusammenhängende Bereiche selektiert werden.


Rheinwerk Computing - Zum Seitenanfang

12.9.4 Listboxen mit Einfachauswahl Zur nächsten ÜberschriftZur vorigen Überschrift

Verwenden Sie eine Listbox, die nur die Auswahl eines Elements zulässt, gestaltet sich der Zugriff auf das entsprechende Element anders als bei einer Listbox mit Mehrfachauswahl. Betrachten wir zuerst Listboxen, deren Eigenschaft SelectionMode auf One eingestellt ist.

Am einfachsten ist es, die Eigenschaft Text der Listbox abzurufen, zum Beispiel:

MessageBox.Show(listBox1.Text)

Nahezu gleichwertig können Sie auch über SelectedItem auf das ausgewählte Listenelement zugreifen, allerdings ist der Rückgabewert dieser Eigenschaft nicht vom Typ String, sondern die Referenz auf das Objekt. Dies macht unter Umständen eine Konvertierung mit ToString() bei dessen Verwendung erforderlich.

MessageBox.Show(listBox1.SelectedItem.ToString())

Eine dritte Möglichkeit bietet sich mit der Eigenschaft Items, die die Referenz auf eine ListBox.ObjectCollection liefert. Die Auflistung stellt einen Indexer bereit, dem der Index des ausgewählten Elements übergeben wird. Weil der Indexer den Typ Object ausgibt, muss die Rückgabe gegebenenfalls in eine Zeichenfolge umgewandelt werden:

MessageBox.Show(listBox1.Items(12).ToString())

Die Indexangabe darf natürlich nicht statisch codiert werden, weil sie sich zur Laufzeit abhängig von der Wahl des Anwenders ändert. Hier hilft uns die Eigenschaft SelectedIndex der Listbox weiter, die den Index des ausgewählten Elements bereitstellt. Die Anweisung zur Auswertung des ausgewählten Elements über den Indexer der Auflistung muss daher so lauten:

MessageBox.Show(listBox1.Items(listBox1.SelectedIndex).ToString())

SelectedIndex ruft nicht nur den Index des ausgewählten Elements in einer Listbox ab, sondern kann ihn auch festlegen. Das ist sehr nützlich, denn standardmäßig wird nach dem Laden und Anzeigen eines Formulars kein Listenelement vorselektiert.

Das Ereignis SelectedIndexChanged

In einer Listbox führt sehr häufig das Anklicken eines Listenelements zur sofortigen Verarbeitung. Statt Click wird das Ereignis SelectedIndexChanged ausgelöst. Sehen wir uns das an einem Beispiel an, dessen Form zwei Listboxen enthält (siehe Abbildung 12.14).

Abbildung 12.14 Form des Beispiels »Einfachauswahl«

In der linken Listbox wird die Liste aller installierten Fonts angezeigt, in der rechten hat der Anwender die Auswahl der Schriftgröße. Die Änderung der Auswahl in einer der beiden Listboxen bewirkt in der Textbox die Anpassung der Zeichenfolge.


'...\WinControls\Selektionen\Einfachauswahl.vb

Public Class Einfachauswahl

  Private Sub Laden(ByVal sender As Object, ByVal e As EventArgs) _ 
  Handles MyBase.Load 
    Dim fonts As New System.Drawing.Text.InstalledFontCollection() 
    Dim familie As FontFamily() = fonts.Families 
    ' Listbox mit den installierten Schriftarten füllen 
    For Each f As FontFamily In familie.Where( _ 
      Function(family) family.IsStyleAvailable(FontStyle.Regular)) 
      Art.Items.Add(f.Name) 
    Next 
    ' Listbox mit einer Auswahl an Schriftgrößen füllen 
    For Each no As Integer In Enumerable.Range(8, 17) 
      Größe.Items.Add(no) 
    Next 
    ' Vorauswahl in den Listboxen 
    Art.SelectedIndex = 0 
    Größe.SelectedIndex = Größe.Items.IndexOf(10) 
    SelectedIndexChanged(Nothing, Nothing) 
  End Sub

  Private Sub SelectedIndexChanged(sender As Object, e As EventArgs) _ 
  Handles Art.SelectedIndexChanged, Größe.SelectedIndexChanged 
    If Not Art.Text.Equals("") AndAlso Not Größe.Text.Equals("") Then _ 
      Beispieltext.Font = New Font(Art.Text, Convert.ToSingle(Größe.Text)) 
  End Sub

End Class

Zuerst werden die beiden Listboxen im Load-Ereignishandler der Form gefüllt. Die Elemente, die in der Listbox Art angeboten werden, beziehen wir aus der Auflistung InstalledFontCollection. Anders als weiter oben gezeigt, sollen nur Schriften erscheinen, die auch »normal« (das heißt zum Beispiel nicht fett oder kursiv) verwendet werden können. Ohne diese Filterung kommt es zu einem Laufzeitfehler, wenn eine Schriftart gewählt wird, die keinen »normalen« Schriftschnitt unterstützt, wie zum Beispiel Monotype Corsiva. Damit nicht immer die gleiche Art einer If-Abfrage auftaucht, verwende ich die Methode Where zur Selektion. Die Methode IsStyleAvailable wird zur Prüfung verwendet.

familie.Where(Function(family) family.IsStyleAvailable(FontStyle.Regular))

Weil in einer Listbox nach dem Start der Anwendung zunächst kein Element vorselektiert ist, sollten wir das per Programmcode für beide Listboxen vorgeben:

Art.SelectedIndex = 0 
Größe.SelectedIndex = Größe.Items.IndexOf(10)

Die Ereignisse SelectedIndexChanged der beiden Listboxen sind mit dem gemeinsamen Handler SelectedIndexChanged verknüpft, der die Schrift in der Textbox an die Auswahl anpasst.

Bitte beachten Sie die If-Abfrage in der Methode, bevor der neue Font zugewiesen wird. Vor der Spezifikation einer konkreten Selektion der Listboxen haben die Text-Eigenschaften den Wert "", der weder ein gültiger Font noch eine gültige Größe ist. Ohne diesen Test kommt es zu einem Laufzeitfehler. Alternativ können Sie statt der Handles-Klausel des Ereignishandlers die Registrierung mit AddHandler vornehmen, wenn diese nach der Festlegung einer Selektion erfolgt.

Im Ereignishandler müssen wir nur die Font-Klasse mit einem passenden Konstruktor instanziieren. Geeignet ist in unserem Fall der Konstruktor, der die Zeichenfolge der Schriftart und die Größe der Schrift erwartet. Das neue Font-Objekt wird der Eigenschaft Font des Textfeldes zugewiesen. Dabei müssen wir allerdings noch den Übergabewert an den zweiten Parameter in den erwarteten Typ Single konvertieren:

Beispieltext.Font = New Font(Art.Text, Convert.ToSingle(Größe.Text))

Die letzte Anweisung im Load-Ereignishandler ist der Aufruf der Methode SelectedIndexChanged. Damit stellen wir sicher, dass nach dem Starten die Schriftart in der Textbox der Voreinstellung in den Listboxen entspricht.


Rheinwerk Computing - Zum Seitenanfang

12.9.5 Listboxen mit Mehrfachauswahl Zur nächsten ÜberschriftZur vorigen Überschrift

Mit der Eigenschaft SelectionMode kann die einfache oder erweiterte Mehrfachauswahl zugelassen werden. Listenelemente mit Mehrfachauswahl verwalten die ausgewählten Listenelemente in zwei Auflistungen:

  • SelectedObjectCollection
  • SelectedIndexCollection.

Der Zugriff erfolgt über die Eigenschaften SelectedIndices und SelectedItems. Beide enthalten die ausgewählten Elemente der Listbox, zu denen sie eine Beziehung entweder über die Referenz oder über den Index herstellen.

Angenommen, Peter, Uwe und Willi bilden in dieser Reihenfolge die Liste der Listbox. Sind Uwe und Willi ausgewählt, enthält SelectedObjectCollection im ihrem ersten, nullindizierten Element den Verweis auf Uwe und im zweiten, mit 1 indizierten Element den Verweis auf Willi. Analog speichert SelectedIndexCollection die Indizes 0 und 1.

Beide Auflistungen verfügen über die üblichen Eigenschaften und Methoden von Auflistungen, beispielsweise Count, Contains, IndexOf, sowie über einen Indexer, um auf ein bestimmtes Element zuzugreifen.

Sehen wir uns an einem Beispiel an, wie ein Listenelement mit Mehrfachauswahl im Programmcode behandelt wird. Die in Abbildung 12.15 gezeigte Form enthält dazu zwei Listboxen, die beide eine Mehrfachauswahl mit SelectionMode=MultiSimple zulassen. In der linken wird nach dem Start der Anwendung eine Namensliste angezeigt. Der Benutzer kann mehrere Einträge in der linken Listbox auswählen und durch Klicken auf den oberen Button die ausgewählten Einträge in die rechte Listbox verschieben. Die markierten und verschobenen Einträge müssen danach in der Ursprungslistbox gelöscht werden. Der umgekehrte Vorgang, das Verschieben aus der rechten in die linke Listbox, verläuft analog.

Abbildung 12.15 Form des Beispiels »Mehrfachauswahl«


'...\WinControls\Selektionen\Mehrfachauswahl.vb

Public Class Mehrfachauswahl

  Private Sub Laden(ByVal sender As Object, ByVal e As EventArgs) _ 
  Handles MyBase.Load 
    Links.Items.AddRange(New String() {"Peter", "Uwe", _ 
      "Michael", "Reiner", "Brigitte", "Thea", "Jackie"}) 
  End Sub

  Private Sub Verschieben(ByVal von As ListBox, ByVal nach As ListBox) 
    Dim elems(von.SelectedItems.Count – 1) As String 
    von.SelectedItems.CopyTo(elems, 0) 
    nach.Items.AddRange(elems) 
    ' ausgewählte Elemente in Quelle löschen 
    For i As Integer = von.SelectedItems.Count – 1 To 0 Step –1 
      von.Items.RemoveAt(von.SelectedIndices(i)) 
    Next 
  End Sub

  Private Sub NachRechts_Click(sender As Object, e As EventArgs) _ 
  Handles NachRechts.Click 
    Verschieben(Links, Rechts) 
  End Sub

  Private Sub NachLinks_Click(sender As Object, e As EventArgs) _ 
  Handles NachLinks.Click 
    Verschieben(Rechts, Links) 
  End Sub

End Class

Im Ereignishandler des Load-Ereignisses der Form wird die linke Listbox gefüllt. Die Ereignishandler zu den Click-Ereignissen der Schaltflächen gleichen sich bis auf die Bezeichner, sodass wir die Funktionalität in der Methode Verschieben() zusammenfassen.

Die Ziel-Listbox soll mit der AddRange-Methode gefüllt werden. AddRange verlangt als Übergabeargument ein Objekt-Array, das wir uns vorher besorgen müssen. Deshalb deklarieren wir zuerst ein Array und initialisieren dieses mit einer Kapazität, die es erlaubt, es mit den ausgewählten Listenelementen aus der Ausgangslistbox füllen zu können. Die Array-Größe resultiert aus der Anzahl der ausgewählten Elemente, die in der Eigenschaft SelectedItems vom Typ SelectedObjectCollection gespeichert ist. Die Count-Eigenschaft der Klasse liefert die Anzahl.

Dim elems(von.SelectedItems.Count – 1) As String

Mit

von.SelectedItems.CopyTo(elems, 0)

kopieren wir den Inhalt der Auflistung SelectedObjectCollection in das zuvor deklarierte Array elems, beginnend beim Index 0. Dieses Array übergeben wir der AddRange-Methode.

Nun müssen wir die ausgewählten und bereits kopierten Listenelemente in der Listbox auch löschen. SelectedIndices der Quell-Listbox liefert uns als Rückgabewert die Indizes der ausgewählten Elemente. Diesen Rückgabewert übergeben wir der Methode RemoveAt der Listbox, die in einer Schleife für jedes markierte Listenelement aufgerufen wird:

For i As Integer = von.SelectedItems.Count – 1 To 0 Step –1 
  von.Items.RemoveAt(von.SelectedIndices(i)) 
Next

Achten Sie darauf, die Schleife ausgehend vom höchsten Zählerwert (der der Anzahl der ausgewählten Elemente minus 1 entspricht) bis 0 zu durchlaufen. Damit wird sichergestellt, dass zuerst das markierte Element mit dem höchsten Index aus der Listbox gelöscht wird und erst zum Schluss das mit dem kleinsten Index. Sie vermeiden so Fehler, die sich aus der Verschiebung der Indizes ergeben, denn auch die Listbox lässt keine unbesetzten Indizes zu und verschiebt alle Nachfolgeelemente um eine Position, um eine entstandene Lücke zu schließen. Die Übergabe des Schleifenzählers an SelectedIndices setzt aber eine konstante Zuordnung voraus, um einen logischen Fehler zu vermeiden.


Rheinwerk Computing - Zum Seitenanfang

12.9.6 Benutzerdefinierte Sortierung Zur nächsten ÜberschriftZur vorigen Überschrift

Wenn Sie die Methode Sort auf die Listenelemente einer Listbox anwenden, werden die sichtbaren Einträge alphabetisch sortiert. Eine Alternative bietet sich nicht an, da die Methode keine entsprechenden Überladungen hat. Manchmal ist es jedoch erforderlich, eine andere Sortierreihenfolge festzulegen.

Angenommen, in einem ListBox-Objekt sollen Objekte vom Typ Person angezeigt werden.

Public Class Person 
  Public Zuname As String 
  Public Vorname As String 
  Public Alter As Integer

  Public Sub New(zuname As String, vorname As String, alter As Integer) 
    Me.Zuname = zuname 
    Me.Vorname = vorname 
    Me.Alter = alter 
  End Sub

  Public Overrides Function ToString() As String 
    Return Me.Zuname & " / " & Me.Vorname & " / " & Me.Alter 
  End Function 
End Class

In der Klasse sind drei Felder öffentlich deklariert. Außerdem ist die Methode ToString() überschrieben, weil die Listbox bei der Übergabe von Referenzen immer den Rückgabewert von ToString() anzeigt. Die Überschreibung stellt sicher, dass zuerst der Zuname, dann der Vorname und zum Schluss das Alter für jeden Eintrag angezeigt werden.

Nun sollen die Elemente in der Listbox nach einem der drei Felder sortiert werden. Die Sorted-Eigenschaft der Listbox leistet das nicht. Wir müssen einen anderen Weg gehen. Dabei hilft uns die überladene Methode Sort der ArrayList weiter, die uns die Möglichkeit gibt, eine Vergleichsklassenreferenz vom Typ IComparer zu übergeben.

Public Overridable Sub Sort(ByVal comparer As IComparer)   'Klasse ArrayList

Eine Vergleichsklasse bereitzustellen, ist kein großes Problem. Eine Hürde ist vielmehr, dass die Methode Sort auf die Referenz einer ArrayList aufgerufen wird, wir jedoch eine Listbox benutzerdefiniert sortieren wollen. Auch über diese Schwierigkeit hilft uns die Klasse ArrayList hinweg: Sie veröffentlicht die statische Methode Adapter, der die Referenz auf ein IList-Objekt übergeben wird.

Public Shared Function Adapter(ByVal list As IList) As ArrayList

Der Zufall will es so, dass die von der Eigenschaft Items zurückgelieferte Referenz vom Typ ListBox.ObjectCollection genau diese Schnittstelle implementiert. Damit hätten wir alle notwendigen Informationen gesammelt, die uns in die Lage versetzen, eine benutzerdefinierte Sortierung der Listboxelemente anzubieten. Das folgende Beispielprogramm zeigt den Programmcode. Die Form in Abbildung 12.16 enthält neben einer Listbox auch drei Schaltflächen. Je nachdem, welche Schaltfläche der Benutzer anklickt, wird die Ausgabe in der Listbox nach einem der drei Felder sortiert.

Abbildung 12.16 Form des Beispiels »Sortierung«


'...\WinControls\Selektionen\Sortierung.vb

Public Class Sortierung 
  Public Class Person 
    ... 
  End Class

  Private sortiert As ArrayList

  Private Class Sortierer : Implements IComparer 
    Private feld As System.Reflection.FieldInfo 
    Sub New(ByVal feld As String) 
      Me.feld = GetType(Person).GetField(feld) 
    End Sub

    Public Function Compare(x As Object, y As Object) As Integer _ 
    Implements System.Collections.IComparer.Compare 
      Return feld.GetValue(x).CompareTo(feld.GetValue(y)) 
    End Function 
  End Class

  Private Sub Laden(ByVal sender As Object, ByVal e As EventArgs) _ 
  Handles MyBase.Load 
    Dim pers As Person() = New Person() { _ 
      New Person("Müller", "Peter", 30), _ 
      New Person("Fischer", "Helmut", 56), _ 
      New Person("Popalowski", "Fred", 22), _ 
      New Person("Heinrich", "Walter", 29), _ 
      New Person("Meier", "Uwe", 12) _ 
    } 
    ' das Array der Listbox übergeben 
    Personen.Items.AddRange(pers) 
    sortiert = ArrayList.Adapter(Personen.Items) 
    sortiert.Sort(New Sortierer("Zuname")) 
  End Sub

  Private Sub Sortieren(ByVal sender As Object, ByVal e As EventArgs) _ 
  Handles Zuname.Click, Vorname.Click, Alter.Click 
    sortiert.Sort(New Sortierer(CType(sender, Button).Name)) 
  End Sub 
End Class

Rheinwerk Computing - Zum Seitenanfang

12.9.7 Auswahlliste mit Datenquelle (DataSource) topZur vorigen Überschrift

Die Add-Methode des Objekts ObjectCollection fügt Listenelemente hinzu. Alternativ weisen Sie der Eigenschaft DataSource eine Referenz auf die Daten der Listbox zu. Eine Bedingung dafür ist, dass das Objekt die Schnittstelle IList implementiert. Üblicherweise wird diese Eigenschaft dazu benutzt, um beispielsweise ein ADO.NET-Objekt vom Typ DataSet zu befüllen. Wir werden uns ADO.NET an späterer Stelle in diesem Buch widmen. Die Vorgehensweise ist bei einem ArrayList-Objekts ganz analog.

Haben Sie die Daten der Listbox mit DataSource festgelegt, müssen Sie noch deren Verwendung festlegen:

  • DisplayMember spezifiziert den Namen der Eigenschaft, die angezeigt wird.
  • DisplayValue spezifiziert den Namen der Eigenschaft, auf den sich SelectedValue bezieht.

Machen wir uns das an einem konkreten Beispiel deutlich:

Public Class Wohnung 
  Private flaeche As Double 
  Private preis As Single 
  Private zimmeranzahl As Integer 
  Public Sub New(flaeche As Double, preis As Single, anzahl As Integer) 
    Me.flaeche = flaeche 
    Me.preis = preis 
    zimmeranzahl = anzahl 
  End Sub

  Public ReadOnly Property Wohnflaeche() As Double 
    Get 
      Return Wohnflaeche 
    End Get 
  End Property

  Public ReadOnly Property Miete() As Single 
    Get 
      Return preis 
    End Get 
  End Property

  Public ReadOnly Property Bezeichnung() As String 
    Get 
      Return zimmeranzahl.ToString() & "-Zimmer-Wohnung" 
    End Get 
  End Property 
End Class

In einer Listbox sollen die Bezeichnungen der Wohnungen angezeigt werden, in zwei Textboxen sowohl der Mietpreis als auch die Wohnfläche des ausgewählten Listenelements (siehe Abbildung 12.17). Wir verwenden die drei Eigenschaften DataSource, DisplayMember und ValueMember, um die Daten der Listbox festzulegen.

Abbildung 12.17 Form des Beispiels »Datenquelle«


'...\WinControls\Selektionen\Datenquelle.vb

Public Class Datenquelle 
  Public Class Wohnung 
    ... 
  End Class

  Private Wohnungen As New ArrayList()

  Private Sub Laden(sender As Object, e As EventArgs) Handles MyBase.Load 
    Wohnungen.Add(New Wohnung(25, 300, 1)) 
    Wohnungen.Add(New Wohnung(54, 470, 2)) 
    Wohnungen.Add(New Wohnung(87, 729, 4)) 
    Wohnungen.Add(New Wohnung(60, 650, 2)) 
    Wohnungen.Add(New Wohnung(75, 680, 3)) 
    Wohnungsliste.DataSource = Wohnungen 
    Wohnungsliste.DisplayMember = "Bezeichnung" 
    Wohnungsliste.ValueMember = "Miete" 
    Wohnungsliste.SelectedIndex = 1 
  End Sub

  Private Sub SelectedIndexChanged(sender As Object, e As EventArgs) _ 
  Handles Wohnungsliste.SelectedIndexChanged 
    Miete.Text = Wohnungsliste.SelectedValue.ToString() 
    Fläche.Text = _ 
      CType(Wohnungsliste.SelectedItem, Wohnung).Wohnfläche.ToString() 
  End Sub 
End Class

DataSource erwartet die Referenz auf ein Objekt, das IList implementiert. Hier ist es ein ArrayList-Objekt mit der Bezeichnung Wohnungen, dem mehrere Wohnung-Objekte hinzugefügt werden. Anschließend wird das ArrayList-Objekt der DataSource-Eigenschaft zugewiesen. Im ListBox-Steuerelement sollen die Inhalte der Eigenschaft Bezeichnung angezeigt werden. Das erreichen wir mit folgender Zuweisung:

Wohnungsliste.DisplayMember = "Bezeichnung"

Als »Wert« wählen wir willkürlich Miete und weisen dessen Name der Eigenschaft ValueMember zu. Die Spezifikation von ValueMember ist optional.

Wohnungsliste.ValueMember = "Miete"

Wählt der Anwender ein Listenelement aus, wird das Ereignis SelectedIndexChanged ausgelöst. In der Textbox Miete zeigen wir den Mietpreis des gewählten Listenelements an, indem wir die Eigenschaft SelectedValue auswerten, die uns den Wert der unter ValueMember genannten Eigenschaft liefert. Die Wohnfläche in der Textbox Fläche wird durch Auswertung von SelectedItem mit anschließender Konvertierung in den Typ Wohnung ermittelt.

Beachten Sie bitte, dass eine Listbox nicht mit Sorted sortiert werden kann, wenn die Eigenschaft DataSource zum Füllen benutzt wird.



Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück
  Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Visual Basic 2008
Visual Basic 2008
Jetzt Buch bestellen


 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Rheinwerk-Shop: Visual Basic 2012






 Visual Basic 2012


Zum Rheinwerk-Shop: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Rheinwerk-Shop: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


Zum Rheinwerk-Shop: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Rheinwerk-Shop: Windows Presentation Foundation






 Windows Presentation
 Foundation


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2009
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern