Skip to content

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

dos>vbc /r:system.dll /r:system.drawing.dll /r:system.windows.forms.dll frm1.vb

dos>frm1

Bei der Ausführung wird das folgende Fenster angezeigt:

Image

Eine grafische Benutzeroberfläche leitet sich in der Regel von der Basisklasse System.Windows.Forms.Form ab:

Public Class Form1
    Inherits Form

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:

Public Event Click As EventHandler

wobei EventHandler eine „delegierte“ Funktion mit folgender Signatur ist:

Public Delegate Sub EventHandler(ByVal sender As Object,ByVal e As EventArgs)

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:

Image

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
   AbortRetryIgnore
  OK
    OKCancel
    RetryCancel
    YesNo
    YesNoCancel

Der Parameter icon kann folgende Werte annehmen:

Asterisk
Error
ebenso Stopp
Exclamation
ebenso Warnung
Hand
Information
ebenso Asterisk
None
Question
Stop
ebenso Hand
Warning

 

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

  1. Starten Sie VS.NET und wählen Sie die Option Fichier/Nouveau/Projet

Image

  1. Geben Sie die Merkmale Ihres Projekts ein
    1. Wählen Sie den Projekttyp aus, den Sie erstellen möchten, in diesem Fall ein VB.NET-Projekt (1)
    2. Wählen Sie den Anwendungstyp aus, den Sie erstellen möchten, hier eine Windows-Anwendung (2)
    3. Geben Sie an, in welchem Ordner Sie den Projektunterordner ablegen möchten (3)
    4. Geben Sie den Namen des Projekts an (4). Dies ist gleichzeitig der Name des Ordners, der die Projektdateien enthält
    5. Der Name dieses Ordners wird unter (5) angezeigt
  1. 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:

Image

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

Image

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:

Image

Auf diese beiden Elemente kann man direkt über das Fenster „Lösungs-Explorer“ zugreifen:

 

Geöffnete Fenster „stauen“ sich im Hauptentwurfsfenster:

Image

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:

Image

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:

Image

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:

Image

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:

Public Class Form1
    Inherits System.Windows.Forms.Form

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]:

Image

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]:

Image

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:

Imports System.Windows.Forms

und kompilieren wir anschließend neu:

dos>vbc /r:system.dll /r:system.windows.forms.dll form1.vb

Diesmal klappt es. Führen wir Folgendes aus:

dos>dir
14/03/2004  11:53               514 Form1.vb
14/03/2004  12:15             3 584 Form1.exe

dos>form1

Image

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:

dos>vbc /r:system.dll /r:system.windows.forms.dll /r:system.drawing.dll /m:form2 form2.vb

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:

Image

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:

Image

Das Eigenschaftenfenster wird daraufhin auf der rechten Seite angezeigt:

Image

Einige dieser Eigenschaften sind besonders zu beachten:

BackColor
um die Hintergrundfarbe des Fensters festzulegen
ForeColor
um die Farbe der Grafiken oder des Textes im Fenster festzulegen
Menu
um dem Fenster ein Menü zuzuweisen
Text
um dem Fenster einen Titel zu geben
FormBorderStyle
um den Fenstertyp festzulegen
Font
um die Schriftart für die Beschriftungen im Fenster festzulegen
Name
zum Festlegen des Fensternamens

Hier legen wir die Eigenschaften Text und Name fest:

Text
Eingabefelder & Schaltflächen – 1
Name
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:
  1. Wählen Sie die verschiedenen Komponenten aus, die gemeinsam formatiert werden sollen (Strg-Taste gedrückt halten)
  2. Wählen Sie die gewünschte Formatierungsart aus
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:
  • Beschriftung 1 (Label)
Wählen Sie die Komponente aus, um
das Eigenschaftenfenster zu öffnen. Ändern Sie darin
ändern Sie die folgenden Eigenschaften:
name: lblSaisie, text: Eingabe
  • Eingabefeld 2 (TextBox)
Wählen Sie die Komponente aus, um ihr
Eigenschaftenfenster zu öffnen. Ändern Sie darin
die folgenden Eigenschaften:
name: txtSaisie, text: nichts eingeben
  • Schaltfläche 3 (Button):
name: cmdAfficher, text: Anzeigen
  • das Fenster selbst: name: frmSaisies&Schaltflächen,
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:

Image

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

Image

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:

sender
das Objekt, das das Ereignis ausgelöst hat (hier die Schaltfläche)
e
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:

Image

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:
Addhandler E, AddressOf P1
Addhandler E, AddressOf P2
...
Addhandler E, AddressOf Pn

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
Closing
Das Formular wird geschlossen
Closed
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:

Image

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
ScrollBars=( None, Horizontal, Vertical, Both)
um festzulegen, ob das Steuerelement Bildlaufleisten haben soll (Horizontal, Vertical, Both) oder nicht (None)
AcceptReturn=(True, False)
Wenn der Wert „true“ ist, bewirkt die Eingabetaste einen Zeilenumbruch
AcceptTab=(True, False)
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
Dropdown-Liste mit Bearbeitungsfeld
DropDownList
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:

Public ReadOnly Property Items As ComboBox.ObjectCollection

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
C.Items(i)
Element i des Kombinationsfelds
C.Add(object o)
Fügt das Objekt o als letztes Element der Combobox hinzu
C.AddRange(object() objets)
Fügt am Ende der Combobox eine Tabelle mit Objekten hinzu
C.Insert(int i, object o)
fügt das Objekt o an Position i der Combobox ein
C.RemoveAt(int i)
entfernt das Element i aus der Combobox
C.Remove(object o)
entfernt das Objekt o aus der Combobox
C.Clear()
Löscht alle Elemente aus der Combobox
C.IndexOf(object o)
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.

Image

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
MouseLeave
Die Maus hat gerade den Bereich des Steuerelements verlassen
MouseMove
Die Maus bewegt sich innerhalb des Steuerbereichs
MouseDown
Druck auf die linke Maustaste
MouseUp
Loslassen der linken Maustaste
DragDrop
Der Benutzer legt ein Objekt auf dem Steuerelement ab
DragEnter
Der Benutzer bewegt ein Objekt in den Bereich des Steuerelements
DragLeave
Der Benutzer verlässt den Bereich des Steuerelements, indem er ein Objekt zieht
DragOver
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:

Image

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.

Image

Image

Image

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

Image

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

Image

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:

Image

In unserem Beispiel werden zwei Eigenschaften verwendet:

 
der Name des Menü-Steuerelements
Text
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:

Image

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:

Image

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“:

Image

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:

Image

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:

Image

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:

Image

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:

Image

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:

Image

Sie leitet sich von mehreren Klassenebenen ab. Von den zahlreichen Eigenschaften und Methoden behalten wir folgende im Blick:

string Filter
die Dateitypen, die in der Dropdown-Liste der Dateitypen im Dialogfeld angeboten werden
int FilterIndex
die Nummer des Dateityps, der standardmäßig in der obigen Liste vorgeschlagen wird. Beginnt bei 0.
String
InitialDirectory
Der Ordner, der ursprünglich zum Speichern der Datei angezeigt wurde
string FileName
Der vom Benutzer angegebene Name der Sicherungsdatei
DialogResult.ShowDialog()
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:

1
Dropdown-Liste, die auf der Eigenschaft „Filter“ basiert. Der standardmäßig vorgeschlagene Dateityp wird durch FilterIndex festgelegt
2
aktuelles Verzeichnis festgelegt, das durch InitialDirectory festgelegt wird, sofern diese Eigenschaft angegeben wurde
3
dem vom Benutzer ausgewählten oder direkt eingegebenen Dateinamen. Dieser ist in der Eigenschaft FileName verfügbar
4
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:
        saveFileDialog1.InitialDirectory = Application.ExecutablePath
  • Man legt die anzuzeigenden Dateitypen fest
        saveFileDialog1.Filter = "Fichiers texte (*.txt)|*.txt|Tous les fichiers (*.*)|*.*"

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
        saveFileDialog1.FilterIndex = 0

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:

string Filter
die in der Dropdown-Liste der Dateitypen im Dialogfeld angebotenen Dateitypen
int FilterIndex
die Nummer des Dateityps, der standardmäßig in der obigen Liste vorgeschlagen wird. Beginnt bei 0.
string InitialDirectory
Der Ordner, der zunächst für die Suche nach der zu öffnenden Datei angezeigt wird
string FileName
Der vom Benutzer angegebene Name der zu öffnenden Datei
DialogResult.ShowDialog()
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:

1
Dropdown-Liste, die auf der Eigenschaft „Filter“ basiert. Der standardmäßig vorgeschlagene Dateityp wird durch FilterIndex festgelegt
2
aktuelles Verzeichnis, festgelegt durch InitialDirectory, sofern diese Eigenschaft angegeben wurde
3
dem gewählten oder vom Benutzer direkt eingegebenen Dateinamen. Dieser ist in der Eigenschaft FileName verfügbar
4
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:
            saveFileDialog1.InitialDirectory=Application.ExecutablePath
  • Die anzuzeigenden Dateitypen werden festgelegt
            saveFileDialog1.Filter = "Fichiers texte (*.txt)|*.txt|Tous les fichiers (*.*)|*.*"
  • Man legt den Dateityp fest, der zu Beginn angezeigt werden soll
            saveFileDialog1.FilterIndex = 0

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:
                    txtTexte.Text=fichier.ReadToEnd
  • 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:

Image

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:

Image

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:

Image

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:

Image

Die Stoppuhr ist angehalten:

Image

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:

Image

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:

Image

Von ihren Eigenschaften werden wir nur die folgenden berücksichtigen:

Interval
Anzahl der Millisekunden, nach deren Ablauf ein Ereignis vom Typ Tick ausgelöst wird.
Tick
das Ereignis, das nach Ablauf von Interval Millisekunden ausgelöst wird
Enabled
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
1
RadioButton
rdOui
angekreuzt, wenn verheiratet
2
RadioButton
rdNon
markieren, wenn unverheiratet
3
NumericUpDown
incEnfants
Anzahl der Kinder des Steuerpflichtigen
Minimum=0, Maximum=20, Schrittweite=1
4
TextBox
txtSalaire
Jahresgehalt des Steuerpflichtigen in F
5
TextBox
txtImpots
Höhe der zu zahlenden Steuer
ReadOnly=true
6
Schaltfläche
btnCalculer
Startet die Steuerberechnung
7
Schaltfläche
btnEffacer
Setzt das Formular beim Laden in seinen ursprünglichen Zustand zurück
8
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:

Image

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

dos>vbc /t:library impots.vb

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“:

Image

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.