5. Grafische Benutzeroberflächen mit VB.NET und VS.NET
Wir möchten hier zeigen, wie man grafische Benutzeroberflächen mit VB.NET erstellt. Zunächst sehen wir uns an, welche Basisklassen der Plattform .NET uns die Erstellung einer grafischen Benutzeroberfläche ermöglichen. Zunächst verwenden wir kein Tool zur automatischen Generierung. Anschließend werden wir Visual Studio.NET (VS.NET) verwenden, ein Entwicklungstool von Microsoft, das die Entwicklung von Anwendungen mit den Sprachen .NET und insbesondere die Erstellung grafischer Benutzeroberflächen erleichtert. Die verwendete Version VS.NET ist die englische Version.
5.1. Grundlagen grafischer Benutzeroberflächen
5.1.1. Ein einfaches Fenster
Betrachten wir den folgenden Code:
' Optionen
Option Strict On
Option Explicit On
' Namensräume
Imports System
Imports System.Drawing
Imports System.Windows.Forms
' Formularklasse
Public Class Form1
Inherits Form
' der Konstruktor
Public Sub New()
' Fenstertitel
Me.Text = "Mon premier formulaire"
' Fensterabmessungen
Me.Size = New System.Drawing.Size(300, 100)
End Sub
' Testfunktion
Public Shared Sub Main(ByVal args() As String)
' Das Formular wird angezeigt
Application.Run(New Form1)
End Sub
End Class
Der obige Code wird kompiliert und anschließend ausgeführt
Bei der Ausführung wird das folgende Fenster angezeigt:

Eine grafische Benutzeroberfläche leitet sich in der Regel von der Basisklasse System.Windows.Forms.Form ab:
Die Basisklasse Form definiert ein Basisfenster mit Schaltflächen zum Schließen, Vergrößern/Verkleinern, einer anpassbaren Größe usw. und verarbeitet die Ereignisse für diese grafischen Objekte. Hier spezialisieren wir die Basisklasse, indem wir ihr einen Titel sowie eine Breite (300) und Höhe (100) zuweisen. Dies geschieht in ihrem Konstruktor:
Public Sub New()
' Fenstertitel
Me.Text = "Mon premier formulaire"
' Fensterabmessungen
Me.Size = New System.Drawing.Size(300, 100)
End Sub
Der Titel des Fensters wird über die Eigenschaft Text festgelegt, die Abmessungen über die Eigenschaft Size. Size ist im Namensraum System.Drawing definiert und stellt eine Struktur dar. Die Prozedur „Main“ startet die grafische Anwendung wie folgt:
Application.Run(New Form1)
Ein Formular vom Typ Form1 wird erstellt und angezeigt. Anschließend überwacht die Anwendung die Ereignisse, die auf dem Formular auftreten (Klicks, Mausbewegungen usw.), und lässt diejenigen ausführen, die das Formular verarbeitet. In diesem Fall verarbeitet unser Formular keine anderen Ereignisse als diejenigen, die von der Basisklasse Form unterstützt werden (Klicks auf Schaltflächen zum Schließen, Vergrößern/Verkleinern, Ändern der Fenstergröße, Verschieben des Fensters usw.).
5.1.2. Ein Formular mit Schaltfläche
Fügen wir nun eine Schaltfläche zu unserem Fenster hinzu:
' Optionen
Option Strict On
Option Explicit On
' Namensräume
Imports System
Imports System.Drawing
Imports System.Windows.Forms
' Formularklasse
Public Class Form1
Inherits Form
' Attribute
Private cmdTest As Button
' der Konstruktor
Public Sub New()
' Titel
Me.Text = "Mon premier formulaire"
' die Abmessungen
Me.Size = New System.Drawing.Size(300, 100)
' eine Schaltfläche
' Erstellung
Me.cmdTest = New Button
' Position
cmdTest.Location = New System.Drawing.Point(110, 20)
' Größe
cmdTest.Size = New System.Drawing.Size(80, 30)
' Bezeichnung
cmdTest.Text = "Test"
' Ereignismanager
AddHandler cmdTest.Click, AddressOf cmdTest_Click
' Schaltfläche zum Formular hinzufügen
Me.Controls.Add(cmdTest)
End Sub
' Ereignis-Handler
Private Sub cmdTest_Click(ByVal sender As Object, ByVal evt As EventArgs)
' Es wurde auf die Schaltfläche geklickt – dies wird gemeldet
MessageBox.Show("Clic sur bouton", "Clic sur bouton", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
' Testfunktion
Public Shared Sub Main(ByVal args() As String)
' Das Formular wird angezeigt
Application.Run(New Form1)
End Sub
End Class
Wir haben dem Formular eine Schaltfläche hinzugefügt:
' eine Schaltfläche
' Erstellung
Me.cmdTest = New Button
' Position
cmdTest.Location = New System.Drawing.Point(110, 20)
' Größe
cmdTest.Size = New System.Drawing.Size(80, 30)
' Bezeichnung
cmdTest.Text = "Test"
' Ereignismanager
AddHandler cmdTest.Click, AddressOf cmdTest_Click
' Schaltfläche zum Formular hinzufügen
Me.Controls.Add(cmdTest)
Die Eigenschaft Location legt mithilfe einer Struktur Point die Koordinaten (110,20) des oberen linken Punktes der Schaltfläche fest. Die Breite und Höhe der Schaltfläche werden mithilfe einer Struktur Size auf (80,30) festgelegt. Mit der Eigenschaft Text der Schaltfläche lässt sich die Beschriftung der Schaltfläche festlegen. Die Klasse „Schaltfläche“ verfügt über ein Click-Ereignis, das wie folgt definiert ist:
wobei EventHandler eine „delegierte“ Funktion mit folgender Signatur ist:
Das bedeutet, dass der Ereignis-Handler [Click] für die Schaltfläche die Signatur des Delegaten [EventHandler] aufweisen muss. Wenn hier auf die Schaltfläche cmdTest geklickt wird, wird die Methode cmdTest_Click aufgerufen. Diese ist gemäß dem vorherigen Muster EventHandler wie folgt definiert:
' Ereignis-Handler
Private Sub cmdTest_Click(ByVal sender As Object, ByVal evt As EventArgs)
' Es wurde auf die Schaltfläche geklickt – dies wird gemeldet
MessageBox.Show("Clic sur bouton", "Clic sur bouton", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Es wird lediglich eine Meldung angezeigt:

Die Klasse wird kompiliert und ausgeführt:
dos>vbc /r:system.dll /r:system.drawing.dll /r:system.windows.forms.dll frm2.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4
dos>frm2
Die Klasse MessageBox dient dazu, Meldungen in einem Fenster anzuzeigen. Wir haben hier den Konstruktor verwendet
Overloads Public Shared Function Show(ByVal owner As IWin32Window,ByVal text As String,ByVal caption As String,ByVal buttons As MessageBoxButtons,ByVal icon As MessageBoxIcon) As DialogResult
text | die anzuzeigende Meldung |
caption | die Überschrift des Fensters |
Schaltflächen | die im Fenster vorhandenen Schaltflächen |
Symbol | das im Fenster angezeigte Symbol |
Der Parameter buttons kann folgende Werte annehmen:
Konstante | Schaltflächen |
![]() | |
![]() | |
![]() | |
![]() | |
![]() | |
![]() |
Der Parameter icon kann folgende Werte annehmen:
![]() | ebenso Stopp | ||
ebenso Warnung | ![]() | ||
ebenso Asterisk | ![]() | ||
![]() | ebenso Hand | ||
![]() |
Die Methode Show ist eine statische Methode, die ein Ergebnis vom Typ System.Windows.Forms.DialogResult zurückgibt, bei dem es sich um eine Aufzählung handelt:
public enum System.Windows.Forms.DialogResult
{
Abort = 0x00000003,
Cancel = 0x00000002,
Ignore = 0x00000005,
No = 0x00000007,
None = 0x00000000,
OK = 0x00000001,
Retry = 0x00000004,
Yes = 0x00000006,
}
Um herauszufinden, welche Schaltfläche der Benutzer zum Schließen des Fensters vom Typ MessageBox gedrückt hat, schreibt man:
dim res as DialogResult=MessageBox.Show(..)
if res=DialogResult.Yes then
' Er hat auf die Schaltfläche „Ja“ geklickt
...
end if
5.2. Erstellen einer grafischen Benutzeroberfläche mit Visual Studio.NET
Wir greifen einige der zuvor behandelten Beispiele wieder auf und erstellen sie nun mit Visual Studio.NET.
5.2.1. Erste Projekterstellung
- Starten Sie VS.NET und wählen Sie die Option Fichier/Nouveau/Projet

- Geben Sie die Merkmale Ihres Projekts ein
![]() |
- Wählen Sie den Projekttyp aus, den Sie erstellen möchten, in diesem Fall ein VB.NET-Projekt (1)
- Wählen Sie den Anwendungstyp aus, den Sie erstellen möchten, hier eine Windows-Anwendung (2)
- Geben Sie an, in welchem Ordner Sie den Projektunterordner ablegen möchten (3)
- Geben Sie den Namen des Projekts an (4). Dies ist gleichzeitig der Name des Ordners, der die Projektdateien enthält
- Der Name dieses Ordners wird unter (5) angezeigt
- Es werden nun eine Reihe von Ordnern und Dateien im Ordner „i4“ erstellt:
Unterordner des Ordners „projekt1“ ![]() |
Von diesen Dateien ist nur eine von Interesse, nämlich die Datei „form1.cs“, bei der es sich um die Quelldatei handelt, die dem von „VS.NET“ erstellten Formular zugeordnet ist. Wir werden darauf zurückkommen.
5.2.2. Die Fenster der Benutzeroberfläche von VS.NET
Die Benutzeroberfläche von VS.NET zeigt nun einige Elemente unseres Projekts i4 an:
Wir haben ein Fenster zur Gestaltung der grafischen Benutzeroberfläche:
![]() |
Indem wir Steuerelemente aus der Symbolleiste (Toolbox 2) auswählen und auf die Fensterfläche (1) ziehen, können wir eine grafische Benutzeroberfläche erstellen. Wenn wir mit der Maus über die „Toolbox“ fahren, vergrößert sich diese und zeigt eine Reihe von Steuerelementen an:

Derzeit verwenden wir noch keines davon. Ebenfalls auf dem Bildschirm von VS.NET finden wir das Fenster des Lösungs-Explorers „Explorer Solution“:

Zunächst werden wir dieses Fenster kaum nutzen. Es zeigt alle Dateien an, aus denen das Projekt besteht. Nur eine davon ist für uns von Interesse: die Quelldatei unseres Programms, hier Form1.vb. Wenn wir mit der rechten Maustaste auf Form1.vb klicken, erscheint ein Menü, über das wir entweder auf den Quellcode unserer grafischen Benutzeroberfläche (Quellcode anzeigen) oder auf die grafische Benutzeroberfläche selbst (View-Designer) zugreifen können:

Auf diese beiden Elemente kann man direkt über das Fenster „Lösungs-Explorer“ zugreifen:
![]() | ![]() |
Geöffnete Fenster „stauen“ sich im Hauptentwurfsfenster:

Hier bezeichnet Form1.vb[Design] das Entwurfsfenster und Form1.vb das Codefenster. Ein Klick auf eine der Registerkarten reicht aus, um zwischen den Fenstern zu wechseln. Ein weiteres wichtiges Fenster, das auf dem Bildschirm von VS.NET angezeigt wird, ist das Eigenschaftenfenster:

Die im Fenster angezeigten Eigenschaften beziehen sich auf das derzeit im grafischen Entwurfsfenster ausgewählte Steuerelement. Über das Menü Affichage gelangt man zu verschiedenen Fenstern des Projekts:

Dort finden sich die soeben beschriebenen Hauptfenster sowie deren Tastaturkürzel.
5.2.3. Ausführen eines Projekts
Obwohl wir noch keinen Code geschrieben haben, verfügen wir bereits über ein ausführbares Projekt. Führen Sie F5 oder Déboguer/Démarrer aus, um es zu starten. Es erscheint das folgende Fenster:

Dieses Fenster kann vergrößert, minimiert, in der Größe angepasst und geschlossen werden.
5.2.4. Der von VS.NET generierte Code
Sehen wir uns den Code (Affichage/Code) unserer Anwendung an:
Public Class Form1
Inherits System.Windows.Forms.Form
#Region „Vom Windows-Forms-Designer generierter Code“
Public Sub New()
MyBase.New()
'Dieser Aufruf wird vom Windows-Forms-Designer benötigt.
InitializeComponent()
'Fügen Sie nach dem Aufruf von InitializeComponent() eine beliebige Initialisierung ein
End Sub
'Die überschriebene Methode entsorgt das Formular, um die Komponentenliste zu bereinigen.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Vom Windows-Forms-Designer erforderlich
Private components As System.ComponentModel.IContainer
'REMARQUE: Die folgende Prozedur wird vom Windows-Form-Designer benötigt
'Sie kann mit dem Windows-Form-Designer geändert werden.
'Ändern Sie sie nicht mit dem Code-Editor.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
Me.Text = "Form2"
End Sub
#Ende der Region
End Class
Eine grafische Benutzeroberfläche leitet sich von der Basisklasse System.Windows.Forms.Form ab:
Die Basisklasse Form definiert ein Basisfenster mit Schaltflächen zum Schließen, Vergrößern/Verkleinern, einer anpassbaren Größe usw. und verarbeitet die Ereignisse dieser grafischen Objekte. Der Formularkonstruktor verwendet eine Methode InitializeComponent, in der die Formularsteuerelemente erstellt und initialisiert werden.
Public Sub New()
MyBase.New()
'Dieser Aufruf wird vom Windows-Forms-Designer benötigt.
InitializeComponent()
'Fügen Sie nach dem Aufruf von InitializeComponent() eine beliebige Initialisierung hinzu
End Sub
Alle weiteren Aufgaben im Konstruktor können nach dem Aufruf von InitializeComponent ausgeführt werden. Die Methode InitializeComponent
Private Sub InitializeComponent()
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 53)
Me.Name = "Form1"
Me.Text = "Form1"
End Sub
Legt den Titel des Fensters „Form1“, seine Breite (292) und seine Höhe (53) fest. Der Titel des Fensters wird durch die Eigenschaft Text und die Abmessungen durch die Eigenschaft Size festgelegt. Size ist im Namensraum System.Drawing definiert und ist eine Struktur. Um diese Anwendung auszuführen, müssen wir das Hauptmodul des Projekts definieren. Dazu verwenden wir die Option [Projets/Propriétés]:

In [Objet de démarrage] geben wir [Form1] an, das Formular, das wir gerade erstellt haben. Um die Ausführung zu starten, verwenden wir die Option [Déboguer/Démarrer]:

5.2.5. Kompilierung in einem DOS-Fenster
Versuchen wir nun, diese Anwendung in einem DOS-Fenster zu kompilieren und auszuführen:
dos>dir form1.vb
14/03/2004 11:53 514 Form1.vb
dos>vbc /r:system.dll /r:system.windows.forms.dll form1.vb
vbc : error BC30420: 'Sub Main' est introuvable dans 'Form1'.
Der Compiler meldet, dass er die Prozedur [Main] nicht findet. Tatsächlich wurde sie von VS.NET nicht generiert. Wir sind ihr jedoch bereits in den vorherigen Beispielen begegnet. Sie hat folgende Form:
Shared Sub Main()
' Die App wird gestartet
Application.Run(New Form1) ' où Form1 est le formulaire
End Sub
Fügen wir den obigen Code in den Code von [Form1.vb] ein und kompilieren wir erneut:
dos>vbc /r:system.dll /r:system.windows.forms.dll form2.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4
Form2.vb(41) : error BC30451: Le nom 'Application' n'est pas déclaré.
Application.Run(New Form2)
~~~~~~~~~~~
In diesem Fall ist der Name „[Application]“ nicht bekannt. Das bedeutet lediglich, dass wir seinen Namensraum „[System.Windows.Forms]“ nicht importiert haben. Fügen wir die folgende Anweisung hinzu:
und kompilieren wir anschließend neu:
Diesmal klappt es. Führen wir Folgendes aus:

Ein Formular vom Typ Form1 wird angelegt und angezeigt. Das Hinzufügen der Prozedur [Main] lässt sich vermeiden, indem man die Option /m des Compilers verwendet, mit der man die auszuführende Klasse angeben kann, falls diese von System.Windows.Form erbt:
Die Option /m:form2 gibt an, dass die auszuführende Klasse die Klasse mit dem Namen [form2] ist.
5.2.6. Ereignisbehandlung
Sobald das Formular angezeigt wird, überwacht die Anwendung die Ereignisse, die auf dem Formular auftreten (Klicks, Mausbewegungen usw.), und lässt diejenigen ausführen, die das Formular verarbeitet. In diesem Fall verarbeitet unser Formular keine anderen Ereignisse als diejenigen, die von der Basisklasse Form unterstützt werden (Klicks auf Schaltflächen zum Schließen, Vergrößern/Verkleinern, Ändern der Fenstergröße, Verschieben des Fensters usw.). Das generierte Formular verwendet ein Attribut components, das nirgendwo verwendet wird. Auch die Methode dispose hat hier keine Funktion. Gleiches gilt für bestimmte verwendete Namespaces (Collections, ComponentModel, Data) sowie für den für das Projekt definierten Namespace projet1. Daher lässt sich der Code in diesem Beispiel wie folgt vereinfachen:
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Public Class Form1
Inherits System.Windows.Forms.Form
' Konstruktor
Public Sub New()
' Erstellung des Formulars mit seinen Komponenten
InitializeComponent()
End Sub
Private Sub InitializeComponent()
' Fenstergröße
Me.Size = New System.Drawing.Size(300, 300)
' Fenstertitel
Me.Text = "Form1"
End Sub
Shared Sub Main()
' Die App wird gestartet
Application.Run(New Form1)
End Sub
End Class
5.2.7. Fazit
Wir werden nun den von VS.NET generierten Code unverändert übernehmen und lediglich unseren eigenen Code hinzufügen, insbesondere um die Ereignisse im Zusammenhang mit den verschiedenen Formularsteuerelementen zu verwalten.
5.3. Fenster mit Eingabefeld, Schaltfläche und Beschriftung
5.3.1. Grafische Gestaltung
Im vorherigen Beispiel hatten wir keine Komponenten in das Fenster eingefügt. Wir beginnen ein neues Projekt mit dem Namen interface2. Dazu folgen wir der zuvor beschriebenen Vorgehensweise zum Erstellen eines Projekts:

Erstellen wir nun ein Fenster mit einer Schaltfläche, einer Beschriftung und einem Eingabefeld:
![]() |
Die Felder lauten wie folgt:
Nr. | Name | Typ | Rolle |
1 | lblSaisie | Bezeichnung | Bezeichnung |
2 | txtSaisie | TextBox | ein Eingabefeld |
3 | btnAfficher | Schaltfläche | um den Inhalt des Eingabefelds in einem Dialogfeld anzuzeigen txtSaisie |
Um dieses Fenster zu erstellen, können Sie wie folgt vorgehen: Klicken Sie mit der rechten Maustaste außerhalb einer Komponente im Fenster und wählen Sie die Option Properties, um auf die Eigenschaften des Fensters zuzugreifen:

Das Eigenschaftenfenster wird daraufhin auf der rechten Seite angezeigt:

Einige dieser Eigenschaften sind besonders zu beachten:
um die Hintergrundfarbe des Fensters festzulegen | |
um die Farbe der Grafiken oder des Textes im Fenster festzulegen | |
um dem Fenster ein Menü zuzuweisen | |
um dem Fenster einen Titel zu geben | |
um den Fenstertyp festzulegen | |
um die Schriftart für die Beschriftungen im Fenster festzulegen | |
zum Festlegen des Fensternamens |
Hier legen wir die Eigenschaften Text und Name fest:
Eingabefelder & Schaltflächen – 1 | |
frmSaisiesBoutons |
Wählen Sie mithilfe der Leiste „Werkzeugkasten“
- die benötigten Komponenten aus
- ziehen Sie sie in das Fenster und passen Sie ihre Abmessungen entsprechend an
![]() | ![]() |
Sobald Sie die Komponente in der „Toolbox“ ausgewählt haben, drücken Sie die Taste „Esc“, um die Symbolleiste auszublenden, und ziehen Sie dann und passen Sie die Größe der Komponente an. Wiederholen Sie diesen Vorgang für alle drei Komponenten Erforderlich: Label, TextBox, Button. Um die Komponenten auszurichten und die Komponenten korrekt zu skalieren, verwenden Sie das Menü Format: | ![]() |
Das Prinzip der Formatierung ist wie folgt:
Mit der Option Align können Sie Komponenten ausrichten | ![]() |
Mit der Option „Make Same Size“ können Sie sicherstellen, dass Komponenten die gleiche Höhe oder die gleiche Breite haben: | ![]() |
Mit der Option „Horizontal Spacing“ lassen sich beispielsweise , Komponenten horizontal auszurichten, wobei gleich großen Abständen zueinander auszurichten. Das Gleiche gilt gilt für die Option „Vertical Spacing“ zur vertikalen Ausrichtung. Mit der Option „Center in Form“ lässt sich eine Komponente horizontal oder vertikal im Fenster zu zentrieren: | ![]() |
Sobald die Komponenten korrekt im Fenster platziert sind, legen Sie ihre Eigenschaften fest. Klicken Sie dazu mit der rechten Maustaste auf die Komponente und wählen Sie die Option Properties:
Wählen Sie die Komponente aus, um das Eigenschaftenfenster zu öffnen. Ändern Sie darin ändern Sie die folgenden Eigenschaften: name: lblSaisie, text: Eingabe
Wählen Sie die Komponente aus, um ihr Eigenschaftenfenster zu öffnen. Ändern Sie darin die folgenden Eigenschaften: name: txtSaisie, text: nichts eingeben
name: cmdAfficher, text: Anzeigen
text: Eingaben & Schaltflächen – 1 | ![]() |
Wir können unser Projekt ausführen (Strg-F5) ausführen, um einen ersten Eindruck vom Fenster in Aktion zu erhalten: | ![]() |
Schließen Sie das Fenster. Nun müssen wir noch die Prozedur schreiben, die bei einem Klick auf die Schaltfläche Afficher ausgeführt wird.
5.3.2. Verarbeitung von Formularereignissen
Sehen wir uns den Code an, der vom grafischen Designer generiert wurde:
...
Public Class frmSaisiesBoutons
Inherits System.Windows.Forms.Form
' Komponenten
Private components As System.ComponentModel.Container = Nothing
Friend WithEvents btnAfficher As System.Windows.Forms.Button
Friend WithEvents lblsaisie As System.Windows.Forms.Label
Friend WithEvents txtsaisie As System.Windows.Forms.TextBox
' Konstruktor
Public Sub New()
InitializeComponent()
End Sub
...
' Initialisierung der Komponenten
Private Sub InitializeComponent()
...
End Sub
End Class
Zunächst ist die spezielle Deklaration der Komponenten zu beachten:
- Das Schlüsselwort „Friend“ gibt an, dass die Sichtbarkeit der Komponente sich auf alle Klassen des Projekts erstreckt
- Das Schlüsselwort „WithEvents“ gibt an, dass die Komponente Ereignisse generiert. Wir wollen uns nun damit befassen, wie diese Ereignisse verarbeitet werden
Rufen Sie das Codefenster des Formulars auf (Ansicht/Code oder F7):
![]() |
Das obige Fenster enthält zwei Dropdown-Listen (1) und (2). Liste (1) ist die Liste der Formularkomponenten:

Liste (2) enthält die Liste der Ereignisse, die mit der in (1) ausgewählten Komponente verknüpft sind:

Eines der mit der Komponente verbundenen Ereignisse wird fett dargestellt (hier „Click“). Dies ist das Standardereignis der Komponente. Der Zugriff auf den Handler für dieses bestimmte Ereignis erfolgt durch Doppelklick auf die Komponente im Entwurfsfenster. VB.net generiert daraufhin automatisch das Grundgerüst des Ereignishandlers im Codefenster und positioniert den Benutzer darauf. Der Zugriff auf die Handler der anderen Ereignisse erfolgt im Codefenster, indem die Komponente in der Liste (1) und das Ereignis in (2) ausgewählt werden. VB.net generiert dann das Grundgerüst des Ereignishandlers oder positioniert den Cursor darauf, falls es bereits generiert wurde:
Private Sub btnAfficher_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAfficher.Click
...
End Sub
Standardmäßig benennt VB.net C_E den Ereignis-Handler für das Ereignis E der Komponente C. Dieser Name kann nach Belieben geändert werden. Davon wird jedoch abgeraten. Entwickler von VB behalten in der Regel den von VB generierten Namen bei, was eine einheitliche Namensgebung in allen VB-Programmen gewährleistet. Die Zuordnung der Prozedur btnAfficher_Click zum Click-Ereignis der Komponente btnAfficher erfolgt nicht über den Namen der Prozedur, sondern über das Schlüsselwort „handles“:
Handles btnAfficher.Click
Im obigen Beispiel gibt das Schlüsselwort „handles“ an, dass die Prozedur das Click-Ereignis der Komponente btnAfficher verarbeitet. Der vorangehende Ereignishandler hat zwei Parameter:
das Objekt, das das Ereignis ausgelöst hat (hier die Schaltfläche) | |
ein Objekt vom Typ EventArgs, das das aufgetretene Ereignis detailliert beschreibt |
Wir werden hier keinen dieser Parameter verwenden. Nun müssen wir nur noch den Code vervollständigen. Hier möchten wir ein Dialogfeld anzeigen, das den Inhalt des Feldes txtSaisie enthält:
Private Sub btnAfficher_Click(ByVal sender As Object, ByVal e As System.EventArgs)
' Der in das Eingabefeld eingegebene Text wird angezeigt TxtSaisie
MessageBox.Show("texte saisi= " + txtsaisie.Text, "Vérification de la saisie", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Wenn wir die Anwendung ausführen, erhalten wir folgendes Ergebnis:

5.3.3. Eine weitere Methode zur Ereignisbehandlung
Für die Schaltfläche btnAfficher hat VS.NET den folgenden Code generiert:
Private Sub InitializeComponent()
...
'
'btnAfficher
'
Me.btnAfficher.Location = New System.Drawing.Point(102, 48)
Me.btnAfficher.Name = "btnAfficher"
Me.btnAfficher.Size = New System.Drawing.Size(88, 24)
Me.btnAfficher.TabIndex = 2
Me.btnAfficher.Text = "Afficher"
...
End Sub
...
' Ereignis-Handler für Klick auf Schaltfläche cmdAfficher
Private Sub btnAfficher_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAfficher.Click
...
End Sub
Wir können die Prozedur btnAfficher_Click auf andere Weise mit dem Click-Ereignis der Schaltfläche btnAfficher verknüpfen:
Private Sub InitializeComponent()
...
'
'btnAfficher
'
Me.btnAfficher.Location = New System.Drawing.Point(102, 48)
Me.btnAfficher.Name = "btnAfficher"
Me.btnAfficher.Size = New System.Drawing.Size(88, 24)
Me.btnAfficher.TabIndex = 2
Me.btnAfficher.Text = "Afficher"
AddHandler btnAfficher.Click, AddressOf btnAfficher_Click
...
End Sub
...
' Ereignis-Handler für Klick auf die Schaltfläche cmdAfficher
Private Sub btnAfficher_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
...
End Sub
Die Prozedur btnAfficher_Click hat das Schlüsselwort „Handles“ verloren und damit ihre Zuordnung zum Ereignis btnAfficher.Click. Diese Zuordnung erfolgt nun mithilfe des Schlüsselworts AddHandler:
AddHandler btnAfficher.Click, AddressOf btnAfficher_Click
Der obige Code, der in die Prozedur InitializeComponent des Formulars eingefügt wird, ordnet dem Ereignis btnAfficher.Click die Prozedur mit dem Namen btnAfficher_Click zu. Außerdem benötigt die Komponente btnAfficher das Schlüsselwort WithEvents nicht mehr:
Friend btnAfficher As System.Windows.Forms.Button
Was ist der Unterschied zwischen den beiden Methoden?
- Mit dem Schlüsselwort „handles“ kann ein Ereignis einer Prozedur nur zum Zeitpunkt der Entwicklung zugeordnet werden. Der Entwickler weiß im Voraus, dass eine Prozedur P die Ereignisse E1, E2, … verarbeiten muss, und schreibt den Code
Private Sub btnAfficher_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) handles E1, E2, ..., En
Es ist tatsächlich möglich, dass eine Prozedur mehrere Ereignisse verarbeitet.
- Mit dem Schlüsselwort `addhandler` kann ein Ereignis zur Laufzeit einer Prozedur zugeordnet werden. Dies ist in einem Produzenten-Verbraucher-Kontext für Ereignisse nützlich. Ein Objekt erzeugt ein bestimmtes Ereignis, das für andere Objekte von Interesse sein könnte. Diese abonnieren das Ereignis beim Erzeuger, um es zu empfangen (beispielsweise eine Temperatur, die einen kritischen Schwellenwert überschritten hat). Während der Ausführung der Anwendung wird der Erzeuger des Ereignisses verschiedene Anweisungen ausführen:
wobei E das vom Produzenten erzeugte Ereignis und Pi die Prozeduren sind, die zu den verschiedenen Konsumentenobjekten dieses Ereignisses gehören. Wir werden in einem späteren Kapitel noch einmal auf eine Produzenten-Konsumenten-Anwendung für Ereignisse zurückkommen.
5.3.4. Fazit
Aus den beiden untersuchten Projekten lässt sich schließen, dass die Arbeit des Entwicklers, sobald die grafische Benutzeroberfläche mit VS.NET erstellt ist, darin besteht, die Ereignisbehandler zu schreiben, die er für diese grafische Benutzeroberfläche verwalten möchte. Wir werden fortan nur noch den Code dieser Ereignisbehandler vorstellen.
5.4. Einige nützliche Komponenten
Wir stellen nun verschiedene Anwendungen vor, die die gängigsten Komponenten nutzen, um deren wichtigste Methoden und Eigenschaften kennenzulernen. Für jede Anwendung präsentieren wir die grafische Benutzeroberfläche und den relevanten Code, insbesondere die Ereignisbehandler.
5.4.1. Formular „Form“
Wir beginnen mit der Vorstellung der unverzichtbaren Komponente, dem Formular, auf das Komponenten platziert werden. Einige seiner grundlegenden Eigenschaften haben wir bereits vorgestellt. Hier gehen wir näher auf einige wichtige Ereignisse eines Formulars ein.
Das Formular wird gerade geladen | |
Das Formular wird geschlossen | |
Das Formular ist geschlossen |
Das Ereignis Load tritt ein, noch bevor das Formular angezeigt wird. Das Ereignis Closing tritt ein, wenn das Formular gerade geschlossen wird. Dieses Schließen kann noch programmgesteuert gestoppt werden. Wir erstellen ein Formular mit dem Namen Form1 ohne Komponenten:

Wir verarbeiten die drei oben genannten Ereignisse:
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
' Erstladen des Formulars
MessageBox.Show("Evt Load", "Load")
End Sub
Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
' Das Formular wird gerade geschlossen
MessageBox.Show("Evt Closing", "Closing")
' Bestätigung wird angefordert
Dim réponse As DialogResult = MessageBox.Show("Voulez-vous vraiment quitter l'application", "Closing", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
If réponse = DialogResult.No Then
e.Cancel = True
End If
End Sub
Private Sub Form1_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
' Das Formular wird gerade geschlossen
MessageBox.Show("Evt Closed", "Closed")
End Sub
Wir verwenden die Funktion MessageBox, um über die verschiedenen Ereignisse benachrichtigt zu werden. Das Ereignis „Closing“ tritt ein, wenn der Benutzer das Fenster schließt. | ![]() |
Wir fragen ihn dann, ob er die Anwendung wirklich beenden möchte: | ![]() |
Wenn er mit „Nein“ antwortet, setzen wir die Eigenschaft Cancel des Ereignisses CancelEventArgs, das die Methode als Parameter erhalten hat. Wenn wir diese Eigenschaft auf False setzen, wird das Schließen des Fensters abgebrochen, andernfalls wird es fortgesetzt: | ![]() |
5.4.2. Label- und Eingabefelder TextBox
Diese beiden Komponenten sind uns bereits begegnet. Label ist eine Textkomponente und TextBox eine Eingabefeldkomponente. Ihre Haupteigenschaft ist Text, die entweder den Inhalt des Eingabefelds oder den Text der Beschriftung bezeichnet. Diese Eigenschaft ist schreib- und lesbar. Das für TextBox üblicherweise verwendete Ereignis ist TextChanged, das signalisiert, dass der Benutzer das Eingabefeld geändert hat. Hier ist ein Beispiel, das das Ereignis TextChanged verwendet, um die Änderungen in einem Eingabefeld zu verfolgen:
![]() |
Nr. | Typ | Name | Rolle |
1 | TextBox | txtSaisie | Eingabefeld |
2 | Bezeichnung | lblControle | zeigt den Text von 1 in Echtzeit an |
3 | Schaltfläche | cmdEffacer | zum Löschen der Felder 1 und 2 |
4 | Schaltfläche | cmdQuitter | zum Beenden der Anwendung |
Der relevante Code dieser Anwendung stammt aus den Ereignisbehandlungsroutinen:
' Klick auf die Schaltfläche „Beenden“
Private Sub cmdQuitter_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles cmdQuitter.Click
' Klick auf die Schaltfläche „Beenden“ – die Anwendung wird beendet
Application.Exit()
End Sub
' Änderung des Felds txtSaisie
Private Sub txtSaisie_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles txtSaisie.TextChanged
' Der Inhalt von TextBox hat sich geändert – er wird in das Label lblControle kopiert
lblControle.Text = txtSaisie.Text
End Sub
' Klick auf die Schaltfläche „Löschen“
Private Sub cmdEffacer_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles cmdEffacer.Click
' Der Inhalt des Eingabefelds wird gelöscht
txtSaisie.Text = ""
End Sub
' Es wurde eine Taste gedrückt
Private Sub txtSaisie_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) _
Handles txtSaisie.KeyPress
' Es wird geprüft, welche Taste gedrückt wurde
Dim touche As Char = e.KeyChar
If touche = ControlChars.Cr Then
MessageBox.Show(txtSaisie.Text, "Contrôle", MessageBoxButtons.OK, MessageBoxIcon.Information)
e.Handled = True
End If
End Sub
Beachten Sie, wie die Anwendung in der Prozedur cmdQuitter_Click beendet wird: Application.Exit(). Das folgende Beispiel verwendet ein mehrzeiliges TextBox:
![]() |
Die Liste der Steuerelemente lautet wie folgt:
Nr. | Typ | Name | Rolle |
1 | TextBox | txtMultiLignes | mehrzeiliges Eingabefeld |
2 | TextBox | txtAjout | einzeiliges Eingabefeld |
3 | Schaltfläche | btnAjouter | Fügt den Inhalt von 2 bis 1 hinzu |
Damit ein TextBox mehrzeilig wird, werden die folgenden Eigenschaften des Steuerelements festgelegt:
um mehrere Textzeilen zuzulassen | |
um festzulegen, ob das Steuerelement Bildlaufleisten haben soll (Horizontal, Vertical, Both) oder nicht (None) | |
Wenn der Wert „true“ ist, bewirkt die Eingabetaste einen Zeilenumbruch | |
Wenn „true“, erzeugt die Tabulatortaste einen Tabulator im Text |
Der relevante Code ist derjenige, der den Klick auf die Schaltfläche [Ajouter] verarbeitet, sowie derjenige, der die Änderung des Eingabefelds [txtAjout] verarbeitet:
' evtl. btnAjouter_Click
Private Sub btnAjouter_Click1(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles btnAjouter.Click
' Der Inhalt von txtAjout wird dem von txtMultilignes hinzugefügt
txtMultilignes.Text &= txtAjout.Text
txtAjout.Text = ""
End Sub
' evt txtAjout_TextChanged
Private Sub txtAjout_TextChanged1(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles txtAjout.TextChanged
' Der Status der Schaltfläche „Hinzufügen“ wird festgelegt
btnAjouter.Enabled = txtAjout.Text.Trim() <> ""
End Sub
5.4.3. Dropdown-Listen ComboBox
![]() | ![]() |
Eine Komponente ComboBox ist eine Dropdown-Liste mit einem Eingabefeld: Der Benutzer kann entweder ein Element aus (2) auswählen oder Text in (1) eingeben. Es gibt drei Arten von ComboBox, die durch die Eigenschaft „Style“ festgelegt werden:
Liste ohne Dropdown-Menü mit Bearbeitungsfeld | |
Dropdown-Liste mit Bearbeitungsfeld | |
Dropdown-Liste ohne Eingabefeld |
Standardmäßig ist der Typ eines ComboBox DropDown. Um die Klasse ComboBox zu finden, geben Sie ComboBox in den Hilfeindex (Aide/Index) ein. Die Klasse ComboBox verfügt über einen einzigen Konstruktor:
Public Sub New() | erstellt ein leeres ComboBox-Objekt |
Die Elemente von ComboBox sind über die Eigenschaft Items verfügbar:
Es handelt sich um eine indizierte Eigenschaft, wobei Items(i) das i-te Element des Kombinationsfelds bezeichnet. Sei C ein Kombinationsfeld und C.Items seine Elementliste. Es gibt folgende Eigenschaften:
Anzahl der Elemente des Kombinationsfelds | |
Element i des Kombinationsfelds | |
Fügt das Objekt o als letztes Element der Combobox hinzu | |
Fügt am Ende der Combobox eine Tabelle mit Objekten hinzu | |
fügt das Objekt o an Position i der Combobox ein | |
entfernt das Element i aus der Combobox | |
entfernt das Objekt o aus der Combobox | |
Löscht alle Elemente aus der Combobox | |
gibt die Position i des Objekts o in der Combobox zurück |
Es mag überraschen, dass ein Kombinationsfeld Objekte enthalten kann, obwohl es üblicherweise Zeichenfolgen enthält. Optisch ist dies der Fall. Wenn ein ComboBox ein Objekt obj enthält, wird die Zeichenfolge obj.ToString(). Wir erinnern uns daran, dass jedes Objekt eine Methode ToString besitzt, die von der Klasse object geerbt wurde und eine Zeichenkette zurückgibt, die das Objekt „repräsentativ“ darstellt. Das in der Combobox C ausgewählte Element ist C.SelectedItem oder C.Items(C.SelectedIndex), wobei C.SelectedIndex die Nummer des ausgewählten Elements ist, wobei diese Nummer beim ersten Element bei Null beginnt.
Bei der Auswahl eines Elements aus der Dropdown-Liste wird das Ereignis SelectedIndexChanged ausgelöst, das dann genutzt werden kann, um über die Änderung der Auswahl in der Combobox informiert zu werden. In der folgenden Anwendung verwenden wir dieses Ereignis, um das Element anzuzeigen, das in der Liste ausgewählt wurde.

Wir zeigen hier nur den relevanten Code des Fensters. Im Formularkonstruktor füllen wir das Kombinationsfeld wie folgt aus:
Public Sub New()
' Formular erstellen
InitializeComponent()
' Ausfüllen des Dropdown-Menüs
cmbNombres.Items.AddRange(New String() {"zéro", "un", "deux", "trois", "quatre"})
' Wir wählen das erste Element der Liste aus
cmbNombres.SelectedIndex = 0
End Sub
Wir verarbeiten das Ereignis SelectedIndexChanged des Kombinationsfelds, das einen neuen ausgewählten Eintrag meldet:
Private Sub cmbNombres_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles cmbNombres.SelectedIndexChanged
' Das ausgewählte Element hat sich geändert – es wird angezeigt
MessageBox.Show("Elément sélectionné : (" & cmbNombres.SelectedItem.ToString & "," & cmbNombres.SelectedIndex & ")", "Combo", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
5.4.4. Bauteil ListBox
Es ist vorgesehen, die folgende Schnittstelle zu erstellen:
![]() |
Die Komponenten dieses Fensters sind folgende:
Nr. | Typ | Name | Funktion/Eigenschaften |
0 | Form | Form1 | Formular – BorderStyle=FixedSingle |
1 | TextBox | txtSaisie | Eingabefeld |
2 | Schaltfläche | btnAjouter | Schaltfläche zum Hinzufügen des Inhalts von Eingabefeld 1 zur Liste 3 |
3 | ListBox | listBox1 | Liste 1 |
4 | ListBox | listBox2 | Liste 2 |
5 | Schaltfläche | btn1TO2 | Überträgt die ausgewählten Elemente aus Liste 1 in Liste 2 |
6 | Schaltfläche | cmd2T0 | führt den umgekehrten Vorgang aus |
7 | Schaltfläche | btnEffacer1 | Liste 1 leeren |
8 | Schaltfläche | btnEffacer2 | Liste 2 leeren |
- Der Benutzer gibt Text in Feld 1 ein. Er fügt ihn mit der Schaltfläche Ajouter (2) zur Liste 1 hinzu. Das Eingabefeld (1) wird daraufhin geleert, und der Benutzer kann ein neues Element hinzufügen.
- Er kann Elemente von einer Liste in die andere übertragen, indem er das zu übertragende Element in einer der Listen auswählt und die entsprechende Übertragungsschaltfläche 5 oder 6 wählt. Das übertragene Element wird am Ende der Zielliste hinzugefügt und aus der Quellliste entfernt.
- Er kann auf ein Element in Liste 1 doppelklicken. Dieses Element wird dann zur Bearbeitung in das Eingabefeld übertragen und aus Liste 1 entfernt.
Die Schaltflächen sind nach folgenden Regeln aktiviert oder deaktiviert:
- Die Schaltfläche Ajouter ist nur aktiviert, wenn das Eingabefeld einen nicht leeren Text enthält
- Die Schaltfläche 5 zum Übertragen von Liste 1 in Liste 2 ist nur aktiviert, wenn in Liste 1 ein Element ausgewählt ist
- Die Schaltfläche 6 zum Übertragen von Liste 2 in Liste 1 ist nur aktiviert, wenn in Liste 2 ein Element ausgewählt ist
- Die Schaltflächen 7 und 8 zum Löschen der Listen 1 und 2 leuchten nur, wenn die zu löschende Liste Elemente enthält.
Unter den oben genannten Bedingungen müssen alle Schaltflächen beim Start der Anwendung deaktiviert sein. Dazu muss die Eigenschaft Enabled der Schaltflächen auf false gesetzt werden. Dies kann bereits bei der Entwicklung erfolgen, wodurch der entsprechende Code in der Methode InitializeComponent generiert wird, oder wir können es selbst im Konstruktor wie folgt umsetzen:
Public Sub New()
' Erstmalige Erstellung des Formulars
InitializeComponent()
' zusätzliche Initialisierungen
' Eine bestimmte Anzahl von Schaltflächen wird deaktiviert
btnAjouter.Enabled = False
btn1TO2.Enabled = False
btn2TO1.Enabled = False
btnEffacer1.Enabled = False
btnEffacer2.Enabled = False
End Sub
Der Status der Schaltfläche Ajouter wird durch den Inhalt des Eingabefelds gesteuert. Das Ereignis TextChanged ermöglicht es uns, Änderungen dieses Inhalts zu verfolgen:
' Änderung im Textfeld „txtsaisie“
Private Sub txtSaisie_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles txtSaisie.TextChanged
' Der Inhalt von txtSaisie hat sich geändert
' Die Schaltfläche „Hinzufügen“ ist nur aktiviert, wenn das Eingabefeld nicht leer ist
btnAjouter.Enabled = txtSaisie.Text.Trim() <> ""
End Sub
Der Status der Übertragungsschaltflächen hängt davon ab, ob ein Element in der Liste, die sie steuern, ausgewählt wurde oder nicht:
' Änderung des ausgewählten Elements ohne Listbox1
Private Sub listBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles listBox1.SelectedIndexChanged
' Ein Element wurde ausgewählt
' Die Schaltfläche „Von 1 nach 2 übertragen“ wird aktiviert
btn1TO2.Enabled = True
End Sub
' Änderung des ausgewählten Elements ohne Listbox 2
Private Sub listBox2_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles listBox2.SelectedIndexChanged
' Ein Element wurde ausgewählt
' Die Schaltfläche „Von 2 nach 1 übertragen“ wird aktiviert
btn2TO1.Enabled = True
End Sub
Der Code, der mit dem Klick auf die Schaltfläche Ajouter verknüpft ist, lautet wie folgt:
' Klick auf die Schaltfläche „Hinzufügen“
Private Sub btnAjouter_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles btnAjouter.Click
' Hinzufügen eines neuen Elements zur Liste 1
listBox1.Items.Add(txtSaisie.Text.Trim())
' Eingabe wurde gelöscht
txtSaisie.Text = ""
' Liste 1 ist nicht leer
btnEffacer1.Enabled = True
' Fokus zurück auf das Eingabefeld
txtSaisie.Focus()
End Sub
Beachten Sie die Methode Focus, mit der der „Fokus“ auf ein Formularsteuerelement gesetzt werden kann. Der Code, der mit dem Klick auf die Schaltflächen Effacer verknüpft ist:
' Klick auf die Schaltfläche „Löschen1“
Private Sub btnEffacer1_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles btnEffacer1.Click
' Liste 1 wird gelöscht
listBox1.Items.Clear()
btnEffacer1.Enabled = False
End Sub
' Klick auf die Schaltfläche „Löschen2“
Private Sub btnEffacer2_Click(ByVal sender As Object, ByVal e As System.EventArgs)
' Liste 2 wird gelöscht
listBox2.Items.Clear()
btnEffacer2.Enabled = False
End Sub
Der Code zum Übertragen der ausgewählten Elemente von einer Liste in die andere:
' Klick auf die Schaltfläche „btn1to2“
Private Sub btn1TO2_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles btn1TO2.Click
' Das ausgewählte Element wird von Liste 1 in Liste 2 übertragen
transfert(listBox1, listBox2)
' Schaltflächen „Löschen“
btnEffacer2.Enabled = True
btnEffacer1.Enabled = listBox1.Items.Count <> 0
' Übertragungsschaltflächen
btn1TO2.Enabled = False
btn2TO1.Enabled = False
End Sub
' Klick auf die Schaltfläche „btn2to1“
Private Sub btn2TO1_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles btn2TO1.Click
' Übertragung des ausgewählten Elements aus Liste 2 in Liste 1
transfert(listBox2, listBox1)
' Schaltflächen „Löschen“
btnEffacer1.Enabled = True
btnEffacer2.Enabled = listBox2.Items.Count <> 0
' Übertragungsschaltflächen
btn1TO2.Enabled = False
btn2TO1.Enabled = False
End Sub
' Übertragung
Private Sub transfert(ByVal l1 As ListBox, ByVal l2 As ListBox)
' Übertragung des ausgewählten Elements aus Liste 1 in Liste 2
' Ein Element ausgewählt?
If l1.SelectedIndex = -1 Then Return
' Hinzufügen zu l2
l2.Items.Add(l1.SelectedItem)
' Löschung in l1
l1.Items.RemoveAt(l1.SelectedIndex)
End Sub
Zunächst erstellen wir eine Methode
Private Sub transfert(ByVal l1 As ListBox, ByVal l2 As ListBox)
die das in der Liste l1 ausgewählte Element in die Liste l2 überträgt. Dadurch benötigen wir nur noch eine Methode statt zwei, um ein Element von listBox1 nach listBox2 oder von listBox2 nach listBox1 zu übertragen. Vor der Übertragung stellen wir sicher, dass tatsächlich ein Element in der Liste l1 ausgewählt ist:
' ein ausgewähltes Element?
If l1.SelectedIndex = -1 Then Return
Die Eigenschaft SelectedIndex hat den Wert -1, wenn derzeit kein Element ausgewählt ist. In den Prozeduren
Private Sub btnXTOY_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles btnXTOY.Click
wird die Liste X in die Liste Y übertragen und der Status bestimmter Schaltflächen geändert, um den neuen Zustand der Listen widerzuspiegeln.
5.4.5. Kontrollkästchen CheckBox, Optionsfelder ButtonRadio
Wir möchten die folgende Anwendung schreiben:
![]() |
Das Fenster enthält folgende Komponenten:
Nr. | Typ | Name | Funktion |
1 | RadioButton | radioButton1 radioButton2 radioButton3 | 3 Optionsfelder |
2 | CheckBox | chechBox1 chechBox2 chechBox3 | 3 Kontrollkästchen |
3 | ListBox | lstValeurs | eine Liste |
Wenn die drei Optionsfelder nacheinander erstellt werden, gehören sie standardmäßig zur selben Gruppe. Wenn also eines aktiviert ist, sind die anderen nicht aktiviert. Das für diese sechs Steuerelemente relevante Ereignis ist das Ereignis CheckChanged, das anzeigt, dass sich der Status des Kontrollkästchens oder des Optionsfelds geändert hat. Dieser Status wird in beiden Fällen durch die boolesche Eigenschaft Check dargestellt, die bei „wahr“ bedeutet, dass das Steuerelement aktiviert ist. Wir haben hier eine einzige Methode verwendet, um die sechs Ereignisse CheckChanged zu verarbeiten, nämlich die Methode affiche:
' zeigt an
Private Sub affiche(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles checkBox1.CheckedChanged, checkBox2.CheckedChanged, checkBox3.CheckedChanged, _
radioButton1.CheckedChanged, radioButton2.CheckedChanged, radioButton3.CheckedChanged
' zeigt den Status des Optionsfelds oder des Kontrollkästchens an
' Ist es ein Kontrollkästchen?
If (TypeOf (sender) Is CheckBox) Then
Dim chk As CheckBox = CType(sender, CheckBox)
lstValeurs.Items.Insert(0, chk.Name & "=" & chk.Checked)
End If
' Ist es ein Optionsfeld?
If (TypeOf (sender) Is RadioButton) Then
Dim rdb As RadioButton = CType(sender, RadioButton)
lstValeurs.Items.Insert(0, rdb.Name & "=" & rdb.Checked)
End If
End Sub
Die Syntax „TypeOf (sender) Is CheckBox“ ermöglicht es, zu überprüfen, ob das Objekt sender vom Typ CheckBox ist. Dadurch können wir anschließend eine Typumwandlung in den genauen Typ von sender vornehmen. Die Methode affiche schreibt in die Liste lstValeurs den Namen der Komponente, die das Ereignis ausgelöst hat, sowie den Wert ihrer Eigenschaft Checked. Bei der Ausführung ist zu sehen, dass ein Klick auf ein Optionsfeld zwei Ereignisse CheckChanged auslöst: eines auf das alte Optionsfeld, das nun den Status „nicht markiert“ annimmt, und das andere auf das neue Optionsfeld, das nun den Status „markiert“ annimmt.
5.4.6. Regler ScrollBar
Es gibt verschiedene Arten von Schiebereglern: den horizontalen Schieberegler (hScrollBar), der vertikale Regler (vScrollBar) und der Inkrementierer (NumericUpDown). | ![]() |
Realisieren wir die folgende Anwendung:
![]() |
Nr. | Typ | Name | Rolle |
1 | hScrollBar | hScrollBar1 | ein horizontaler Regler |
2 | hScrollBar | hScrollBar2 | ein horizontaler Regler, der den Schwankungen von Regler 1 folgt |
3 | TextBox | txtValeur | zeigt den Wert des horizontalen Reglers an ReadOnly=true, um Eingaben zu verhindern |
4 | NumericUpDown | Inkrementierer | ermöglicht die Festlegung des Wertes des Reglers 2 |
- Ein Schieberegler vom Typ ScrollBar ermöglicht es dem Benutzer, einen Wert aus einem Bereich ganzer Zahlen auszuwählen, der durch den „Streifen“ des Schiebereglers symbolisiert wird, auf dem sich ein Cursor bewegt. Der Wert des Schiebereglers ist in seiner Eigenschaft „Value“ verfügbar.
- Bei einem horizontalen Schieberegler stellt das linke Ende den Minimalwert des Bereichs dar, das rechte Ende den Maximalwert und der Schieberegler den aktuell ausgewählten Wert. Bei einem vertikalen Schieberegler wird der Minimalwert durch das obere Ende und der Maximalwert durch das untere Ende dargestellt. Diese Werte werden durch die Eigenschaften „Minimum“ und „Maximum“ repräsentiert und sind standardmäßig auf 0 bzw. 100 gesetzt.
- Ein Klick auf die Endpunkte des Schiebereglers verändert den Wert um einen Schritt (positiv oder negativ), abhängig vom angeklickten Endpunkt mit der Bezeichnung SmallChange, der standardmäßig 1 ist.
- Ein Klick auf beiden Seiten des Schiebereglers verändert den Wert um einen Schritt (positiv oder negativ), je nach dem angeklickten Ende, das als „LargeChange“ bezeichnet wird und standardmäßig den Wert 10 hat.
- Wenn man auf das obere Ende eines vertikalen Schiebereglers klickt, verringert sich dessen Wert. Dies kann den durchschnittlichen Benutzer überraschen, der normalerweise erwartet, dass der Wert „steigt“. Dieses Problem lässt sich beheben, indem man den Eigenschaften SmallChange und LargeChange einen negativen Wert zuweist.
- Diese fünf Eigenschaften (Value, Minimum, Maximum, SmallChange, LargeChange) sind sowohl lesbar als auch beschreibbar.
- Das wichtigste Ereignis des Umrichters ist dasjenige, das eine Wertänderung signalisiert: das Scroll-Ereignis.
Eine Komponente mit der Bezeichnung NumericUpDown befindet sich in der Nähe des Umrichters: Auch sie verfügt über die Eigenschaften Minimum, Maximum und Value, deren Standardwerte 0, 100 und 0 sind. Hier wird die Eigenschaft Value jedoch in einem Eingabefeld angezeigt, das fester Bestandteil des Steuerelements ist. Der Benutzer kann diesen Wert selbst ändern, es sei denn, die Eigenschaft ReadOnly des Steuerelements wurde auf „wahr“ gesetzt. Der Wert des Inkrements wird durch die Eigenschaft Increment festgelegt, Standardwert ist 1. Das wichtigste Ereignis der Komponente NumericUpDown ist dasjenige, das eine Wertänderung signalisiert: das Ereignis ValueChanged. Der relevante Code unserer Anwendung lautet wie folgt:
Das Formular wird beim Erstellen formatiert:
' Konstruktor
Public Sub New()
' Erstmalige Erstellung des Formulars
InitializeComponent()
' Dem Frequenzumrichter 2 werden die gleichen Eigenschaften wie dem Frequenzumrichter 1 zugewiesen
hScrollBar2.Minimum = hScrollBar1.Value
hScrollBar2.Minimum = hScrollBar1.Minimum
hScrollBar2.Maximum = hScrollBar1.Maximum
hScrollBar2.LargeChange = hScrollBar1.LargeChange
hScrollBar2.SmallChange = hScrollBar1.SmallChange
' dasselbe gilt für den Inkrementierer
incrémenteur.Minimum = hScrollBar1.Value
incrémenteur.Minimum = hScrollBar1.Minimum
incrémenteur.Maximum = hScrollBar1.Maximum
incrémenteur.Increment = hScrollBar1.SmallChange
' dem TextBox wird der Wert von Umrichter 1 zugewiesen
txtValeur.Text = "" & hScrollBar1.Value
End Sub
Der Handler, der die Wertänderungen des Frequenzumrichters 1 überwacht:
' Steuerung des Umrichters hscrollbar1
Private Sub hScrollBar1_Scroll(ByVal sender As Object, ByVal e As System.Windows.Forms.ScrollEventArgs) _
Handles hScrollBar1.Scroll
' Wertänderung des Reglers 1
' Der Wert wird auf den Regler 2 und das Textfeld TxtValeur übertragen
hScrollBar2.Value = hScrollBar1.Value
txtValeur.Text = "" & hScrollBar1.Value
End Sub
Der Handler, der die Wertänderungen des Frequenzumrichters 2 überwacht:
' Steuerung des Reglers hscrollbar2
Private Sub hScrollBar2_Scroll(ByVal sender As Object, ByVal e As System.Windows.Forms.ScrollEventArgs) _
Handles hScrollBar2.Scroll
' Jede Änderung am Regler 2 wird gesperrt
' indem man ihn zwingt, den Wert von Regler 1 beizubehalten
e.NewValue = hScrollBar1.Value
End Sub
Der Manager, der die Änderungen der Steuerung incrémenteur überwacht:
' Inkrementer-Steuerung
Private Sub incrémenteur_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles incrémenteur.ValueChanged
' Der Wert des Reglers 2 wird festgelegt
hScrollBar2.Value = CType(incrémenteur.Value, Integer)
End Sub
5.5. Mausereignisse
Wenn man in einem Container zeichnet, ist es wichtig, die Position der Maus zu kennen, um beispielsweise bei einem Klick einen Punkt anzuzeigen. Mausbewegungen lösen Ereignisse in dem Container aus, in dem sich die Maus bewegt.
![]() | ![]() |
Die Maus hat gerade den Bereich des Steuerelements betreten | |
Die Maus hat gerade den Bereich des Steuerelements verlassen | |
Die Maus bewegt sich innerhalb des Steuerbereichs | |
Druck auf die linke Maustaste | |
Loslassen der linken Maustaste | |
Der Benutzer legt ein Objekt auf dem Steuerelement ab | |
Der Benutzer bewegt ein Objekt in den Bereich des Steuerelements | |
Der Benutzer verlässt den Bereich des Steuerelements, indem er ein Objekt zieht | |
Der Benutzer fährt mit einem Objekt über den Steuerungsbereich |
Hier ist ein Programm, mit dem man besser verstehen kann, wann die verschiedenen Mausereignisse auftreten:
![]() |
Nr. | Typ | Name | Rolle |
1 | Bezeichnung | lblPosition | um die Position der Maus in Formular 1, Liste 2 oder Schaltfläche 3 anzuzeigen |
2 | ListBox | lstEvts | um andere Mausereignisse als MouseMove anzuzeigen |
3 | Button | btnEffacer | um den Inhalt von 2 zu löschen |
Es gibt folgende Ereignisbehandler. Um die Mausbewegungen auf den drei Steuerelementen zu verfolgen, schreibt man nur einen einzigen Ereignisbehandler:
' evtl. form1_mousemove
Private Sub Form1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles MyBase.MouseMove, lstEvts.MouseMove, btnEffacer.MouseMove, lstEvts.MouseMove
' Mausbewegung – Anzeige der Koordinaten (X, Y) der Maus
lblPosition.Text = "(" & e.X & "," & e.Y & ")"
End Sub
Man muss wissen, dass sich das Koordinatensystem jedes Mal ändert, wenn die Maus in den Bereich eines Steuerelements gelangt. Sein Ursprung (0,0) ist die obere linke Ecke des Steuerelements, auf dem sich die Maus befindet. Bei der Ausführung sieht man daher deutlich die Änderung der Koordinaten, wenn man mit der Maus vom Formular zur Schaltfläche wechselt. Um diese Änderungen des Mausbereichs besser zu erkennen, kann man die Eigenschaft Cursor der Steuerelemente verwenden:

Mit dieser Eigenschaft lässt sich die Form des Mauszeigers festlegen, sobald dieser in den Bereich des Steuerelements eintritt. In unserem Beispiel haben wir den Mauszeiger für das Formular selbst auf „Default“, für Liste 2 auf „Hand“ und für Schaltfläche 3 auf „No“ festgelegt, wie die folgenden Screenshots zeigen.



In der Methode [InitializeComponent] lautet der durch diese Auswahl generierte Code wie folgt:
Me.lstEvts.Cursor = System.Windows.Forms.Cursors.Hand
Me.btnEffacer.Cursor = System.Windows.Forms.Cursors.No
Um zudem die Maus-Ein- und -Ausgänge in Liste 2 zu erkennen, verarbeiten wir die Ereignisse MouseEnter und MouseLeave aus derselben Liste:
' evt lstEvts_MouseEnter
Private Sub lstEvts_MouseEnter(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles lstEvts.MouseEnter
affiche("MouseEnter sur liste")
End Sub
' Ereignis lstEvts_MouseLeave
Private Sub lstEvts_MouseLeave(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles lstEvts.MouseLeave
affiche("MouseLeave sur liste")
End Sub
' zeigt
Private Sub affiche(ByVal message As String)
' Die Meldung wird oben in der Liste der Ereignisse angezeigt
lstEvts.Items.Insert(0, message)
End Sub

Um Klicks auf das Formular zu verarbeiten, behandeln wir die Ereignisse MouseDown und MouseUp:
' Ereignis Form1_MouseDown
Private Sub Form1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles MyBase.MouseDown
affiche("MouseDown sur formulaire")
End Sub
' Ereignis Form1_MouseUp
Private Sub Form1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles MyBase.MouseUp
affiche("MouseUp sur formulaire")
End Sub

Und schließlich der Code für den Klick-Handler der Schaltfläche Effacer:
' Ereignis btnEffacer_Click
Private Sub btnEffacer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles btnEffacer.Click
' löscht die Liste der Ereignisse
lstEvts.Items.Clear()
End Sub
5.6. Ein Fenster mit Menü erstellen
Schauen wir uns nun an, wie man ein Fenster mit Menü erstellt. Wir werden das folgende Fenster erstellen:
![]() |
Das Steuerelement 1 ist ein schreibgeschütztes TextBox (ReadOnly=true) mit dem Namen txtStatut. Die Menüstruktur sieht wie folgt aus:
![]() | ![]() |
Menüoptionen sind Steuerelemente wie andere visuelle Komponenten und verfügen über Eigenschaften und Ereignisse. Beispielsweise die Eigenschaftstabelle der Menüoption A1:

In unserem Beispiel werden zwei Eigenschaften verwendet:
der Name des Menü-Steuerelements | |
die Bezeichnung der Menüoption |
Die Eigenschaften der verschiedenen Menüoptionen in unserem Beispiel lauten wie folgt:
Name | Text |
mnuA | Optionen A |
mnuA1 | A1 |
mnuA2 | A2 |
mnuA3 | A3 |
mnuB | Optionen B |
mnuB1 | B1 |
mnuSep1 | - (Trennzeichen) |
mnuB2 | B2 |
mnuB3 | B3 |
mnuB31 | B31 |
mnuB32 | B32 |
Um ein Menü zu erstellen, wählt man die Komponente „MainMenu“ in der Leiste „ToolBox“ aus:

Man erhält dann ein leeres Menü, das im Formular mit leeren Feldern mit der Bezeichnung „Type Here“ angezeigt wird. Dort müssen lediglich die verschiedenen Menüoptionen eingegeben werden:

Um ein Trennzeichen zwischen zwei Optionen einzufügen, wie oben zwischen den Optionen „B1“ und „B2“, positionieren Sie den Cursor an der Stelle, an der das Trennzeichen im Menü stehen soll, klicken Sie mit der rechten Maustaste und wählen Sie die Option „Insert Separator“:

Wenn man die Anwendung mit Strg+F5 startet, erscheint ein Formular mit einem Menü, das derzeit noch keine Funktion hat. Die Menüoptionen werden wie Komponenten behandelt: Sie verfügen über Eigenschaften und Ereignisse. Wählen Sie in [fenêtre de code] die Komponente mnuA1 aus und wählen Sie anschließend die zugehörigen Ereignisse aus:

Wenn oben das Ereignis Click generiert wird, generiert VS.NET automatisch die folgende Prozedur:
Private Sub mnuA1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles mnuA.Click
....
End Sub
Wir könnten so für alle Menüoptionen vorgehen. Hier kann für alle Optionen dieselbe Prozedur verwendet werden. Daher benennen wir die vorherige Prozedur in affiche um und deklarieren die Ereignisse, die sie verarbeitet:
Private Sub affiche(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles mnuA1.Click, mnuA2.Click, mnuB1.Click, mnuB2.Click, mnuB31.Click, mnuB32.Click
' zeigt in TextBox den Namen des ausgewählten Untermenüs an
txtStatut.Text = (CType(sender, MenuItem)).Text
End Sub
Bei dieser Methode beschränken wir uns darauf, die Eigenschaft Text der Menüoption an der Ereignisquelle anzuzeigen. Die Ereignisquelle sender ist vom Typ object. Da die Menüoptionen vom Typ MenuItem sind, ist hier eine Typumwandlung von object in MenuItem erforderlich. Führen Sie die Anwendung aus und wählen Sie die Option A1 aus, um die folgende Meldung zu erhalten:

Der relevante Code dieser Anwendung ist neben dem der Methode affiche der für die Erstellung des Menüs im Formular-Konstruktor (InitializeComponent):
Private Sub InitializeComponent()
Me.mainMenu1 = New System.Windows.Forms.MainMenu
Me.mnuA = New System.Windows.Forms.MenuItem
Me.mnuA1 = New System.Windows.Forms.MenuItem
Me.mnuA2 = New System.Windows.Forms.MenuItem
Me.mnuA3 = New System.Windows.Forms.MenuItem
Me.mnuB = New System.Windows.Forms.MenuItem
Me.mnuB1 = New System.Windows.Forms.MenuItem
Me.mnuB2 = New System.Windows.Forms.MenuItem
Me.mnuB3 = New System.Windows.Forms.MenuItem
Me.mnuB31 = New System.Windows.Forms.MenuItem
Me.mnuB32 = New System.Windows.Forms.MenuItem
Me.txtStatut = New System.Windows.Forms.TextBox
Me.mnuSep1 = New System.Windows.Forms.MenuItem
Me.SuspendLayout()
'
' mainMenu1
'
Me.mainMenu1.MenuItems.AddRange(New System.Windows.Forms.MenuItem() {Me.mnuA, Me.mnuB})
'
' mnuA
'
Me.mnuA.Index = 0
Me.mnuA.MenuItems.AddRange(New System.Windows.Forms.MenuItem() {Me.mnuA1, Me.mnuA2, Me.mnuA3})
Me.mnuA.Text = "Options A"
'
' mnuA1
'
Me.mnuA1.Index = 0
Me.mnuA1.Text = "A1"
'
' mnuA2
'
Me.mnuA2.Index = 1
Me.mnuA2.Text = "A2"
'
' mnuA3
'
Me.mnuA3.Index = 2
Me.mnuA3.Text = "A3"
'
' mnuB
'
Me.mnuB.Index = 1
Me.mnuB.MenuItems.AddRange(New System.Windows.Forms.MenuItem() {Me.mnuB1, Me.mnuSep1, Me.mnuB2, Me.mnuB3})
Me.mnuB.Text = "Options B"
'
' mnuB1
'
Me.mnuB1.Index = 0
Me.mnuB1.Text = "B1"
'
' mnuB2
'
Me.mnuB2.Index = 2
Me.mnuB2.Text = "B2"
'
' mnuB3
'
Me.mnuB3.Index = 3
Me.mnuB3.MenuItems.AddRange(New System.Windows.Forms.MenuItem() {Me.mnuB31, Me.mnuB32})
Me.mnuB3.Text = "B3"
'
' mnuB31
'
Me.mnuB31.Index = 0
Me.mnuB31.Text = "B31"
'
' mnuB32
'
Me.mnuB32.Index = 1
Me.mnuB32.Text = "B32"
'
' txtStatut
'
Me.txtStatut.Location = New System.Drawing.Point(8, 8)
Me.txtStatut.Name = "txtStatut"
Me.txtStatut.ReadOnly = True
Me.txtStatut.Size = New System.Drawing.Size(112, 20)
Me.txtStatut.TabIndex = 0
Me.txtStatut.Text = ""
'
' mnuSep1
'
Me.mnuSep1.Index = 1
Me.mnuSep1.Text = "-"
'
' Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(136, 42)
Me.Controls.Add(txtStatut)
Me.Menu = Me.mainMenu1
Me.Name = "Form1"
Me.Text = "Menus"
Me.ResumeLayout(False)
End Sub
Beachten Sie die Anweisung, die das Menü mit dem Formular verknüpft:
Me.Menu = Me.mainMenu1
5.7. Nicht-visuelle Komponenten
Wir befassen uns nun mit einer Reihe nicht-visueller Komponenten: Diese werden bei der Gestaltung verwendet, sind jedoch bei der Ausführung nicht sichtbar.
5.7.1. Dialogfelder OpenFileDialog und SaveFileDialog
Wir werden die folgende Anwendung erstellen:
![]() |
Die Steuerelemente sind folgende:
Nr. | Typ | Name | Rolle |
1 | TextBox mehrzeilig | txtTexte | vom Benutzer eingegebener oder aus einer Datei hochgeladener Text |
2 | Schaltfläche | btnSauvegarder | ermöglicht das Speichern des Textes aus Feld 1 in einer Textdatei |
3 | Schaltfläche | btnCharger | ermöglicht das Einlesen des Inhalts einer Textdatei in 1 |
4 | Button | btnEffacer | löscht den Inhalt von 1 |
Es werden zwei nicht-visuelle Steuerelemente verwendet:

Wenn sie aus dem „ToolBox“ entnommen und auf das Formular gezogen werden, werden sie in einem separaten Bereich am unteren Rand des Formulars platziert. Die „Dialog“-Komponenten werden aus dem „ToolBox“ entnommen:

Der Code der Schaltfläche „Effacer“ ist einfach:
Private Sub btnEffacer_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles btnEffacer.Click
' Das Eingabefeld wird gelöscht
txtTexte.Text = ""
End Sub
Die Klasse SaveFileDialog ist wie folgt definiert:

Sie leitet sich von mehreren Klassenebenen ab. Von den zahlreichen Eigenschaften und Methoden behalten wir folgende im Blick:
die Dateitypen, die in der Dropdown-Liste der Dateitypen im Dialogfeld angeboten werden | |
die Nummer des Dateityps, der standardmäßig in der obigen Liste vorgeschlagen wird. Beginnt bei 0. | |
Der Ordner, der ursprünglich zum Speichern der Datei angezeigt wurde | |
Der vom Benutzer angegebene Name der Sicherungsdatei | |
Methode, die das Dialogfeld zum Speichern anzeigt. Liefert ein Ergebnis vom Typ DialogResult. |
Die Methode ShowDialog zeigt ein Dialogfeld an, das in etwa wie folgt aussieht:
![]() |
Dropdown-Liste, die auf der Eigenschaft „Filter“ basiert. Der standardmäßig vorgeschlagene Dateityp wird durch FilterIndex festgelegt | |
aktuelles Verzeichnis festgelegt, das durch InitialDirectory festgelegt wird, sofern diese Eigenschaft angegeben wurde | |
dem vom Benutzer ausgewählten oder direkt eingegebenen Dateinamen. Dieser ist in der Eigenschaft FileName verfügbar | |
Schaltflächen „Speichern“/„Abbrechen“. Wenn die Schaltfläche Enregistrer verwendet wird, liefert die Funktion ShowDialog das Ergebnis DialogResult.OK |
Die Speicherroutine lässt sich wie folgt schreiben:
Private Sub btnSauvegarder_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles btnSauvegarder.Click
' Das Eingabefeld wird in einer Textdatei gespeichert
' Das Dialogfeld wird konfiguriert savefileDialog1
saveFileDialog1.InitialDirectory = Application.ExecutablePath
saveFileDialog1.Filter = "Fichiers texte (*.txt)|*.txt|Tous les fichiers (*.*)|*.*"
saveFileDialog1.FilterIndex = 0
' Das Dialogfeld wird angezeigt und das Ergebnis abgerufen
If saveFileDialog1.ShowDialog() = DialogResult.OK Then
' Der Dateiname wird abgerufen
Dim nomFichier As String = saveFileDialog1.FileName
Dim fichier As StreamWriter = Nothing
Try
' Die Datei wird zum Schreiben geöffnet
fichier = New StreamWriter(nomFichier)
' Der Text wird in die Datei geschrieben
fichier.Write(txtTexte.Text)
Catch ex As Exception
' Problem
MessageBox.Show("Problème à l'écriture du fichier (" + ex.Message + ")", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
Finally
' Die Datei wird geschlossen
Try
fichier.Close()
Catch
End Try
End Try
End If
End Sub
- Als Ausgangsverzeichnis wird der Ordner festgelegt, der die ausführbare Datei der Anwendung enthält:
- Man legt die anzuzeigenden Dateitypen fest
Beachten Sie die Syntax der Filter: filter1|filter2|..|filtren, wobei filteri = Text|Dateimuster gilt. Hier hat der Benutzer die Wahl zwischen *.txt- und *.*-Dateien.
- Legen Sie den zu Beginn anzuzeigenden Dateityp fest
Hier werden dem Benutzer zunächst die Dateien vom Typ *.txt angezeigt.
- Das Dialogfeld wird angezeigt und das Ergebnis abgerufen
If saveFileDialog1.ShowDialog() = DialogResult.OK Then
- Solange das Dialogfeld angezeigt wird, hat der Benutzer keinen Zugriff mehr auf das Hauptformular (sogenanntes modales Dialogfeld). Der Benutzer legt den Namen der zu speichernden Datei fest und verlässt das Dialogfeld entweder über die Schaltfläche „Speichern“, über die Schaltfläche „Abbrechen“ oder durch Schließen des Dialogfelds. Das Ergebnis der Methode ShowDialog lautet nur dann DialogResult.OK, wenn der Benutzer die Schaltfläche Enregistrer verwendet hat, um das Dialogfeld zu verlassen.
- Ist dies geschehen, befindet sich der Name der zu erstellenden Datei nun in der Eigenschaft FileName des Objekts saveFileDialog1. Man kehrt dann zur klassischen Erstellung einer Textdatei zurück. Dort schreibt man den Inhalt von TextBox: txtTexte.Text und behandelt dabei eventuell auftretende Ausnahmen.
Die Klasse OpenFileDialog ist der Klasse SaveFileDialog sehr ähnlich und stammt aus derselben Klassenlinie. Von diesen Eigenschaften und Methoden behalten wir folgende im Blick:
die in der Dropdown-Liste der Dateitypen im Dialogfeld angebotenen Dateitypen | |
die Nummer des Dateityps, der standardmäßig in der obigen Liste vorgeschlagen wird. Beginnt bei 0. | |
Der Ordner, der zunächst für die Suche nach der zu öffnenden Datei angezeigt wird | |
Der vom Benutzer angegebene Name der zu öffnenden Datei | |
Methode, die das Dialogfeld zum Speichern anzeigt. Liefert ein Ergebnis vom Typ DialogResult. |
Die Methode ShowDialog zeigt ein Dialogfeld an, das in etwa wie folgt aussieht:
![]() |
Dropdown-Liste, die auf der Eigenschaft „Filter“ basiert. Der standardmäßig vorgeschlagene Dateityp wird durch FilterIndex festgelegt | |
aktuelles Verzeichnis, festgelegt durch InitialDirectory, sofern diese Eigenschaft angegeben wurde | |
dem gewählten oder vom Benutzer direkt eingegebenen Dateinamen. Dieser ist in der Eigenschaft FileName verfügbar | |
Schaltflächen „Öffnen“/„Abbrechen“. Wenn die Schaltfläche Ouvrir verwendet wird, liefert die Funktion ShowDialog das Ergebnis DialogResult.OK |
Die Prozedur zum Öffnen lässt sich wie folgt schreiben:
Private Sub btnCharger_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles btnCharger.Click
' Eine Textdatei wird in das Eingabefeld geladen
' Das Dialogfeld wird konfiguriert: openfileDialog1
openFileDialog1.InitialDirectory = Application.ExecutablePath
openFileDialog1.Filter = "Fichiers texte (*.txt)|*.txt|Tous les fichiers (*.*)|*.*"
openFileDialog1.FilterIndex = 0
' Das Dialogfeld wird angezeigt und das Ergebnis wird abgerufen
If openFileDialog1.ShowDialog() = DialogResult.OK Then
' Der Dateiname wird abgerufen
Dim nomFichier As String = openFileDialog1.FileName
Dim fichier As StreamReader = Nothing
Try
' Die Datei wird im Lesemodus geöffnet
fichier = New StreamReader(nomFichier)
' Die gesamte Datei wird gelesen und in die Variable TextBox gespeichert
txtTexte.Text = fichier.ReadToEnd()
Catch ex As Exception
' Problem
MessageBox.Show("Problème à la lecture du fichier (" + ex.Message + ")", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
Finally
' Die Datei wird geschlossen
Try
fichier.Close()
Catch
End Try
End Try
End If
End Sub
- Als Ausgangsverzeichnis wird das Verzeichnis festgelegt, das die ausführbare Datei der Anwendung enthält:
- Die anzuzeigenden Dateitypen werden festgelegt
- Man legt den Dateityp fest, der zu Beginn angezeigt werden soll
Hier werden dem Benutzer zunächst Dateien vom Typ *.txt angezeigt.
- Das Dialogfeld wird angezeigt und das Ergebnis abgerufen
If openFileDialog1.ShowDialog() = DialogResult.OK Then
Solange das Dialogfeld angezeigt wird, hat der Benutzer keinen Zugriff mehr auf das Hauptformular (sogenanntes modales Dialogfeld). Der Benutzer legt den Namen der zu öffnenden Datei fest und verlässt das Dialogfeld entweder über die Schaltfläche „Öffnen“, über die Schaltfläche „Abbrechen“ oder durch Schließen des Dialogfelds. Das Ergebnis der Methode ShowDialog ist nur dann DialogResult.OK, wenn der Benutzer die Schaltfläche Ouvrir verwendet hat, um das Dialogfeld zu verlassen.
- Ist dies geschehen, befindet sich der Name der zu erstellenden Datei nun in der Eigenschaft FileName des Objekts openFileDialog1. Man kehrt dann zum klassischen Lesen einer Textdatei zurück. Beachten Sie die Methode, mit der die gesamte Datei gelesen werden kann:
- Der Inhalt der Datei wird in die Objekte TextBox und txtTexte übertragen. Eventuell auftretende Ausnahmen werden behandelt.
5.7.2. Dialogfelder FontColor und ColorDialog
Wir setzen das vorherige Beispiel fort und stellen zwei neue Schaltflächen vor:
![]() |
Nr. | Typ | Name | Funktion |
6 | Schaltfläche | btnCouleur | zur Festlegung der Schriftfarbe von TextBox |
7 | Schaltfläche | btnPolice | um die Schriftart von TextBox festzulegen |
Wir fügen dem Formular ein Steuerelement ColorDialog und ein Steuerelement FontDialog hinzu:

Die Klassen FontDialog und ColorDialog verfügen über eine Methode ShowDialog, die der Methode ShowDialog der Klassen OpenFileDialog und SaveFileDialog. Die Methode ShowDialog der Klasse ColorDialog ermöglicht die Auswahl einer Farbe:

Wenn der Benutzer das Dialogfeld über die Schaltfläche OK verlässt, ist das Ergebnis der Methode ShowDialog DialogResult.OK und die ausgewählte Farbe befindet sich in der Eigenschaft Color des verwendeten Objekts ColorDialog. Die Methode ShowDialog der Klasse FontDialog ermöglicht die Auswahl einer Schriftart:

Wenn der Benutzer das Dialogfeld über die Schaltfläche OK verlässt, ist das Ergebnis der Methode ShowDialog DialogResult.OK und die ausgewählte Schriftart befindet sich in der Eigenschaft Font des verwendeten Objekts FontDialog. Wir haben die Elemente zur Verarbeitung der Klicks auf die Schaltflächen Couleur und Police:
Private Sub btnCouleur_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles btnCouleur.Click
' Auswahl einer Textfarbe
If colorDialog1.ShowDialog() = DialogResult.OK Then
' Die Eigenschaft „forecolor“ von TextBox wird geändert
txtTexte.ForeColor = colorDialog1.Color
End If
End Sub
Private Sub btnPolice_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles btnPolice.Click
' Auswahl einer Schriftart
If fontDialog1.ShowDialog() = DialogResult.OK Then
' Ändern der Eigenschaft „font“ von TextBox
txtTexte.Font = fontDialog1.Font
End If
End Sub
5.7.3. Timer
Wir schlagen hier vor, die folgende Anwendung zu schreiben:
![]() |
Nr. | Typ | Name | Rolle |
1 | TextBox, ReadOnly=true | txtChrono | zeigt eine Stoppuhr an |
2 | Schaltfläche | btnArretMarche | Start-/Stopp-Taste der Stoppuhr |
3 | Timer | timer1 | Komponente, die hier jede Sekunde ein Ereignis auslöst |
Die Stoppuhr läuft:

Die Stoppuhr ist angehalten:

Um den Inhalt von TextBox und txtChrono jede Sekunde zu ändern, benötigen wir eine Komponente, die jede Sekunde ein Ereignis generiert, das wir abfangen können, um die Anzeige der Stoppuhr zu aktualisieren. Diese Komponente ist die Timer:

Sobald diese Komponente im Formular installiert ist (im Bereich der nicht-visuellen Komponenten), wird im Formularkonstruktor ein Objekt vom Typ Timer erstellt. Die Klasse System.Windows.Forms.Timer ist wie folgt definiert:

Von ihren Eigenschaften werden wir nur die folgenden berücksichtigen:
Anzahl der Millisekunden, nach deren Ablauf ein Ereignis vom Typ Tick ausgelöst wird. | |
das Ereignis, das nach Ablauf von Interval Millisekunden ausgelöst wird | |
Schaltet den Timer ein (true) oder aus (false) |
In unserem Beispiel heißt der Timer timer1 und timer1.Interval ist auf 1000 ms (1 s) eingestellt. Das Ereignis Tick wird daher jede Sekunde ausgelöst. Der Klick auf die Schaltfläche „Stopp/Start“ wird durch die folgende Prozedur verarbeitet:
Private Sub btnArretMarche_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles btnArretMarche.Click
' Aus oder Ein?
If btnArretMarche.Text = "Marche" Then
' Notierung der Startzeit
début = DateTime.Now
' Anzeige der Startzeit
txtChrono.Text = "00:00:00"
' Der Timer wird gestartet
timer1.Enabled = True
' Die Beschriftung der Schaltfläche wird geändert
btnArretMarche.Text = "Arrêt"
' Ende
Return
End If '
If btnArretMarche.Text = "Arrêt" Then
' Timer stoppen
timer1.Enabled = False
' Die Beschriftung der Schaltfläche wird geändert
btnArretMarche.Text = "Marche"
' Ende
Return
End If
End Sub
Private Sub timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles timer1.Tick
' Eine Sekunde ist vergangen
Dim maintenant As DateTime = DateTime.Now
Dim durée As TimeSpan = DateTime.op_Subtraction(maintenant, début)
txtChrono.Text = "" + durée.Hours.ToString("d2") + ":" + durée.Minutes.ToString("d2") + ":" + durée.Seconds.ToString("d2")
End Sub
Die Beschriftung der Schaltfläche „Stopp/Start“ lautet entweder „Stopp“ oder „Start“. Daher muss ein Test dieser Beschriftung durchgeführt werden, um zu entscheiden, welche Aktion ausgeführt werden soll.
- Im Fall von „Start“ wird die Startzeit in einer globalen Variablen des Formularobjekts gespeichert, der Timer wird gestartet (Enabled=true) und die Beschriftung der Schaltfläche ändert sich zu „Stopp“.
- Im Fall von „Stopp“ wird der Timer angehalten (Enabled=false) und die Beschriftung der Schaltfläche auf „Start“ geändert.
Public Class Timer1
Inherits System.Windows.Forms.Form
Private WithEvents timer1 As System.Windows.Forms.Timer
Private WithEvents btnArretMarche As System.Windows.Forms.Button
Private components As System.ComponentModel.IContainer
Private WithEvents txtChrono As System.Windows.Forms.TextBox
Private WithEvents label1 As System.Windows.Forms.Label
' Instanzvariablen
Private début As DateTime
Das oben genannte Attribut début ist in allen Methoden der Klasse bekannt. Nun müssen wir noch das Ereignis Tick am Objekt timer1 behandeln, das jede Sekunde auftritt:
Private Sub timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles timer1.Tick
' Eine Sekunde ist vergangen
Dim maintenant As DateTime = DateTime.Now
Dim durée As TimeSpan = DateTime.op_Subtraction(maintenant, début)
txtChrono.Text = "" + durée.Hours.ToString("d2") + ":" + durée.Minutes.ToString("d2") + ":" + durée.Seconds.ToString("d2")
End Sub
Wir berechnen die seit dem Start der Stoppuhr verstrichene Zeit. Wir erhalten ein Objekt vom Typ TimeSpan, das eine Zeitspanne darstellt. Diese muss in der Stoppuhr im Format hh:mm:ss angezeigt werden. Dazu verwenden wir die Eigenschaften Hours, Minutes, Seconds des Objekts TimeSPan, die jeweils die Stunden, Minuten und Sekunden der Zeitdauer darstellen, die wir im Format ToString("d2") anzeigen, um eine zweistellige Darstellung zu erhalten.
5.8. Das Beispiel IMPOTS
Wir greifen auf die Anwendung IMPOTS zurück, die bereits zweimal behandelt wurde. Nun fügen wir ihr eine grafische Benutzeroberfläche hinzu:
![]() |
Die Steuerelemente sind wie folgt
Nr. | Typ | Name | Rolle |
RadioButton | rdOui | angekreuzt, wenn verheiratet | |
RadioButton | rdNon | markieren, wenn unverheiratet | |
NumericUpDown | incEnfants | Anzahl der Kinder des Steuerpflichtigen Minimum=0, Maximum=20, Schrittweite=1 | |
TextBox | txtSalaire | Jahresgehalt des Steuerpflichtigen in F | |
TextBox | txtImpots | Höhe der zu zahlenden Steuer ReadOnly=true | |
Schaltfläche | btnCalculer | Startet die Steuerberechnung | |
Schaltfläche | btnEffacer | Setzt das Formular beim Laden in seinen ursprünglichen Zustand zurück | |
Schaltfläche | btnQuitter | zum Beenden der Anwendung |
Funktionsregeln
- Die Schaltfläche „Berechnen“ bleibt deaktiviert, solange das Gehaltsfeld leer ist
- Wenn sich bei Start der Berechnung herausstellt, dass das Gehalt falsch ist, wird ein Fehler gemeldet:

Das Programm ist unten aufgeführt. Es verwendet die Klasse „impot“, die im Kapitel über Klassen erstellt wurde. Ein Teil des Codes, der automatisch von „VS.NET“ generiert wird, wurde hier nicht wiedergegeben.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
' Optionen
Option Explicit On
Option Strict On
' Namensräume
Imports System
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.Data
' Formularklasse
Public Class frmImpots
Inherits System.Windows.Forms.Form
Private WithEvents label1 As System.Windows.Forms.Label
Private WithEvents rdOui As System.Windows.Forms.RadioButton
Private WithEvents rdNon As System.Windows.Forms.RadioButton
Private WithEvents label2 As System.Windows.Forms.Label
Private WithEvents txtSalaire As System.Windows.Forms.TextBox
Private WithEvents label3 As System.Windows.Forms.Label
Private WithEvents label4 As System.Windows.Forms.Label
Private WithEvents groupBox1 As System.Windows.Forms.GroupBox
Private WithEvents btnCalculer As System.Windows.Forms.Button
Private WithEvents btnEffacer As System.Windows.Forms.Button
Private WithEvents btnQuitter As System.Windows.Forms.Button
Private WithEvents txtImpots As System.Windows.Forms.TextBox
Private components As System.ComponentModel.Container = Nothing
Private WithEvents incEnfants As System.Windows.Forms.NumericUpDown
' für die Steuerberechnung erforderliche Datentabellen
Private limites() As Decimal = {12620D, 13190D, 15640D, 24740D, 31810D, 39970D, 48360D, 55790D, 92970D, 127860D, 151250D, 172040D, 195000D, 0D}
Private coeffR() As Decimal = {0D, 0.05D, 0.1D, 0.15D, 0.2D, 0.25D, 0.3D, 0.35D, 0.4D, 0.45D, 0.55D, 0.5D, 0.6D, 0.65D}
Private coeffN() As Decimal = {0D, 631D, 1290.5D, 2072.5D, 3309.5D, 4900D, 6898.5D, 9316.5D, 12106D, 16754.5D, 23147.5D, 30710D, 39312D, 49062D}
' Steuerobjekt
Private objImpôt As impot = Nothing
Public Sub New()
InitializeComponent()
' Initialisierung des Formulars
btnEffacer_Click(Nothing, Nothing)
btnCalculer.Enabled = False
' Anlegen eines Steuerobjekts
Try
objImpôt = New impot(limites, coeffR, coeffN)
Catch ex As Exception
MessageBox.Show("Impossible de créer l'objet impôt (" + ex.Message + ")", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error)
' Das Eingabefeld für das Gehalt wird gesperrt
txtSalaire.Enabled = False
End Try 'try-catch
End Sub
Protected Overloads Sub Dispose(ByVal disposing As Boolean)
....
End Sub
Private Sub InitializeComponent()
Me.btnQuitter = New System.Windows.Forms.Button
Me.groupBox1 = New System.Windows.Forms.GroupBox
Me.btnEffacer = New System.Windows.Forms.Button
Me.btnCalculer = New System.Windows.Forms.Button
Me.txtSalaire = New System.Windows.Forms.TextBox
Me.label1 = New System.Windows.Forms.Label
Me.label2 = New System.Windows.Forms.Label
Me.label3 = New System.Windows.Forms.Label
Me.rdNon = New System.Windows.Forms.RadioButton
Me.txtImpots = New System.Windows.Forms.TextBox
Me.label4 = New System.Windows.Forms.Label
Me.rdOui = New System.Windows.Forms.RadioButton
Me.incEnfants = New System.Windows.Forms.NumericUpDown
Me.groupBox1.SuspendLayout()
CType(Me.incEnfants, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
....
End Sub 'InitializeComponent
Public Shared Sub Main()
Application.Run(New frmImpots)
End Sub 'Main
Private Sub btnEffacer_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles btnEffacer.Click
' Formular zurücksetzen
incEnfants.Value = 0
txtSalaire.Text = ""
txtImpots.Text = ""
rdNon.Checked = True
End Sub 'btnEffacer_Click
Private Sub txtSalaire_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles txtSalaire.TextChanged
' Status der Schaltfläche „Berechnen“
btnCalculer.Enabled = txtSalaire.Text.Trim() <> ""
End Sub 'txtSalaire_TextChanged
Private Sub btnQuitter_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles btnQuitter.Click
' Anwendung beenden
Application.Exit()
End Sub 'btnQuitter_Click
Private Sub btnCalculer_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles btnCalculer.Click
' Ist das Gehalt korrekt?
Dim intSalaire As Integer = 0
Try
' Lohn abrufen
intSalaire = Integer.Parse(txtSalaire.Text)
' Er muss >=0 sein
If intSalaire < 0 Then
Throw New Exception("")
End If
Catch ex As Exception
' Fehlermeldung
MessageBox.Show(Me, "Salaire incorrect", "Erreur de saisie", MessageBoxButtons.OK, MessageBoxIcon.Error)
' Fokus auf fehlerhaftes Feld
txtSalaire.Focus()
' Auswahl des Textes im Eingabefeld
txtSalaire.SelectAll()
' Zurück zur Benutzeroberfläche
Return
End Try 'try-catch
' Das Gehalt ist korrekt – die Steuer wird berechnet
txtImpots.Text = "" & CLng(objImpôt.calculer(rdOui.Checked, CInt(incEnfants.Value), intSalaire))
End Sub 'btnCalculer_Click
End Class
Wir verwenden hier die Assemblierungsdatei impots.dll, die aus der Kompilierung der Klasse „impots“ aus Kapitel 2 resultiert. Zur Erinnerung: Diese Assemblierungsdatei kann im Konsolenmodus mit dem Befehl
Dieser Befehl erzeugt die Datei „impots.dll“, die als Assemblage bezeichnet wird. Diese Assemblage kann anschließend in verschiedenen Projekten verwendet werden. Hier, in unserem Projekt unter „VS.NET“, nutzen wir das Fenster „Projekteigenschaften“:

Um eine Referenz (eine Baugruppe) hinzuzufügen, klicken wir mit der rechten Maustaste auf den Schlüssel „References“ oben, wählen die Option „[Ajouter une référence]“ und geben die Baugruppe „[impots.dll]“ an, die wir zuvor im Projektordner abgelegt haben:
dos>dir
01/03/2004 14:39 9 250 gui_impots.vb
01/03/2004 14:37 4 096 impots.dll
01/03/2004 14:41 12 288 gui_impots.exe
Sobald die Assembly [impots.dll] in das Projekt eingebunden wurde, wird die Klasse [impots] dem Projekt bekannt. Zuvor war dies nicht der Fall. Eine andere Methode besteht darin, die Quelldatei impots.vb in das Projekt einzubinden. Dazu klickt man im Fenster „Projekteigenschaften“ mit der rechten Maustaste auf das Projekt, wählt die Option „[Ajouter/Ajouter un élément existant]“ aus und gibt die Datei „impots.vb“ an.















































