Galileo Computing < openbook >
Galileo Computing - Bücher zur Programmierung und Softwareentwicklung
Galileo Computing - Bücher zur Programmierung und Softwareentwicklung

...powered by haas.homelinux.net...

Einstieg in VB.NET von René Martin
- Für Programmiereinsteiger -
Einstieg in VB.NET
gp Kapitel 2 Aufbauwissen VB.NET
  gp 2.1 Ein zweiter Dialog
  gp 2.2 Ein Süßigkeitenautomat
  gp 2.3 Eine Listbox
  gp 2.4 With ... End With
  gp 2.5 Die Liste
  gp 2.6 Eine ComboBox
  gp 2.7 Die Select-Case-Verzweigung
  gp 2.8 Ein theoretischer Exkurs: Ereignisse
    gp 2.8.1 Dynamisch ein- und ausblenden
    gp 2.8.2 Dynamische Größenänderung
  gp 2.9 Zwei völlig überflüssige Beispiele
  gp 2.10 Schleifen
  gp 2.11 For ... Next
  gp 2.12 Do ... Loop
  gp 2.13 Eine Schleife über den Süßigkeiten
  gp 2.14 Ein theoretischer Exkurs: Sammlungen oder Collections
  gp 2.15 Die For ... Each-Schleife
  gp 2.16 Schleifen spielerisch
    gp 2.16.1 Primzahlen
    gp 2.16.2 Fibonacci-Zahlen
    gp 2.16.3 ggT und kgV
    gp 2.16.4 Ein Scherz zum Schluss
  gp 2.17 Rekursives Programmieren
  gp 2.18 Arrays (Datenfelder)
    gp 2.18.1 Eindimensionale Arrays
    gp 2.18.2 Mehrdimensionale Arrays
  gp 2.19 Konstanten
  gp 2.20 Funktionen
  gp 2.21 Zusammenfassung


Galileo Computing

2.15 Die For ... Each-Schleife  toptop

In diesem Zusammenhang ist eine weitere Schleifenform interessant und wichtig – die For ... Each-Schleife. Sie ist mit der For ... Next-Schleife vergleichbar. Diesmal zählt allerdings keine Variable hoch, sondern die Schleife greift auf alle Elemente einer Sammlung zu.

Das könnte dann wie folgt aussehen:

Dim lstElement as Object
For Each lstElement In lstListe.Items
   MessageBox.Show(Ctype(lstElement, String))
Next

lstListe.Items ist die Sammlung der Einträge; auf jedes einzelne lstElement kann zugegriffen werden. Damit der Inhalt angezeigt werden kann, muss das Objekt erst mit der Funktion CType umgewandelt werden. Analog funktioniert dies bei einem Formular. Auf ihm sitzen mehrere Steuerelemente. Will man mit einer Schleife auf alle zugreifen, dann beispielsweise so:

Dim ctl As System.Windows.Forms.Control
Dim strAnzeige As String
For Each ctl in Me.Controls
   strAnzeige &= vbCr & ctl.Name
Next
MessageBox.Show(ctl.Name)

Natürlich könnte man auch deklarieren:

Dim ctl As Object
Abbildung

Abbildung 2.32   Die Liste der Steuerelemente auf dem Formular

Und nun sollen alle ausgewählten Einträge angezeigt werden. Hierzu wird eine Schleife benötigt. Dabei hilft die Sammlung SelectedItems:

Dim lstElement As Object
Dim strListe As String
For Each lstElement In lstListe.SelectedItems
   strListe &= vbCr & CType(lstElement, String)
Next
MessageBox.Show(strListe)

Wer den Zugriff über Objektvariablen nicht mag oder sich damit schwer tut, der kann die Schleife auch »klassisch« als Zählerschleife gestalten:

Dim intZähler As Integer
For intZähler = 0 To _
   Me.lstListe.SelectedItems.Count - 1
   strListe &= vbCr & Me.lstListe.SelectedItems(intZähler)
Next
        MessageBox.Show(strListe)

Auf den ersten Blick erstaunlich gestaltet sich die Lösung des nächsten Problems: Der Benutzer soll per »Knopfdruck« einen oder mehrere Einträge löschen. Bei einer Einzelauswahl wäre dies kein Problem. Dort kann aus der Sammlung der Items der markierte Eintrag gelöscht werden:

Me.lstListe.Items.Remove(Me.lstListe.SelectedItem)

Lässt man allerdings eine Zählerschleife über die Items laufen, dann könnte man sie löschen, oder?

Dim intZähler As Integer
   For intZähler = 0 To _
Me.lstListe.SelectedItems.Count – 1
   Me.lstListe.Items.Remove _
(Me.lstListe.SelectedItems(intZähler))
   Next

Ein Test zeigt, dass zwar ein markiertes Element gelöscht wird, allerdings kommt es bei mehreren zu einer Fehlermeldung. Was passiert? Bei zwei markierten Einträgen wird zuerst die Nummer 0 gelöscht. Danach wird der Zähler auf 1 gesetzt. Nun wird die Nummer 1 gelöscht; allerdings ist sie nun aufgerückt und hat den Platz 1 (Nummer 0) eingenommen. Somit kann eine Nummer 1 nicht mehr gefunden werden.

Abbildung

Abbildung 2.33   Mehrere Einträge können gelöscht werden.

Es gibt mehrere Lösungen für dieses Problem. Man könnte jedes Mal die Nummer 0 löschen. Oder man lässt die Schleife vom letzten zum ersten Item laufen:

Dim intZähler As Integer
   For intZähler = Me.lstListe.SelectedItems _
      .Count – 1 To 0 Step -1
   Me.lstListe.Items.Remove _
   (Me.lstListe.SelectedItems(intZähler))
   Next

Das Löschen der gesamten Liste ist einfach:

Me.lstListe.Items.Clear

Nun sollen sich neben der Liste noch zwei Buttons befinden, mit deren Hilfe vorhandene Einträge nach oben, beziehungsweise nach unten geschoben werden. Ein Eintrag könnte folgendermaßen gelöscht und verschoben werden:

Dim intPos As Integer
   Dim objEintrag As Object
   objEintrag = Me.lstListe.SelectedItem
   intPos = Me.lstListe.SelectedIndex
   Me.lstListe.Items.Remove(objEintrag)
   Me.lstListe.Items.Insert(intPos - 1, _
   objEintrag)

Natürlich könnte man es auch ohne Variablen schreiben, aber der Code würde schnell unübersichtlich werden.

Und wenn man eine Schleife darum baut (und ein klein wenig den Code ändert), dann kann man alle markierten Einträge um eine Position nach oben verschieben:

Dim intZähler As Integer
Dim intPos As Integer
Dim objEintrag As Object
For intZähler = 0 To _
   Me.lstListe.SelectedItems.Count – 1
   objEintrag = Me.lstListe.SelectedItem
   intPos = Me.lstListe.Items.IndexOf _
      (Me.lstListe.SelectedItem)
   Me.lstListe.Items.Remove(objEintrag)
   Me.lstListe.Items.Insert(intPos - 1, _
   objEintrag)
Next
Abbildung

Abbildung 2.34   Duplo und Mars sind zwischen Gummibärchen und Lutscher.

Abbildung

Abbildung 2.35   Sie werden um eine Position nach oben verschoben.

Der geneigte Leser darf sich gerne daran versuchen, wie man die markierten Einträge nach unten verschieben kann. Ein Tipp: Es müssen zwei Kleinigkeiten verändert werden.

Allerdings wird ein Fehler gemeldet, wenn der Benutzer den ersten Eintrag ausgewählt hat. Dies sollte man überprüfen. Mit einem einfachen Trick kann auf die Schleife verzichtet werden. SelectedItem gibt bei einer Mehrfachauswahl immer den obersten Eintrag zurück. Und bei diesem kann überprüft werden, ob er die Nummer 0 besitzt:

If Me.lstListe.Items.IndexOf _
   (Me.lstListe.SelectedItem) = 0 Then
   MessageBox.Show("Geht nicht")
   Exit Sub
End If

Damit der Benutzer nicht ständig Fehlermeldungen um die Ohren geschlagen bekommt, kann man ihm dadurch helfen, dass ein Verschieben nach oben nicht mehr möglich ist, wenn einer der markierten Einträge der erste ist. Das zugehörige Objekt ist die Liste, das Ereignis lautet SelectedIndexChanged.

Abbildung

Abbildung 2.36   Das Verschieben nach oben ist nicht mehr möglich.

Private Sub lstListe_SelectedIndexChanged _
(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles _
lstListe.SelectedIndexChanged
   If Me.lstListe.SelectedItems.Count > 0 Then
      If Me.lstListe.Items.IndexOf _
         (Me.lstListe.SelectedItem) = 0 Then
         Me.butNachOben.Enabled = False
      Else
         Me.butNachOben.Enabled = True
      End If
   End If
End Sub

Etwas schwieriger ist das Ausschalten des Buttons »NachUnten«, wenn bei einer Mehrfachauswahl der letzte Eintrag ausgewählt wurde. Über die Variable intPosLetzte wird die Position des letzten markierten Eintrags ermittelt. Stimmt diese Zahl mit der Anzahl der Einträge der Liste überein, dann wird der Button »NachUnten« deaktiviert:

Dim intPosLetzte As Integer
intPosLetzte = lstListe.Items.IndexOf 
(lstListe.SelectedItems(lstListe.SelectedItems.Count – 1))
   If intPosLetzte = lstListe.Items.Count – 1 Then
      butNachUnten.Enabled = False
   Else
      butNachUnten.Enabled = True
   End If
...
Abbildung

Abbildung 2.37   Nun kann nichts mehr nach unten verschoben werden.

  

VB.NET

Einstieg in ASP.NET

Einstieg in C#

Visual C#

VB.NET und Datenbanken

Einstieg in XML