Tutorial: Erstellen einer neuen WPF-App mit .NET

In diesem kurzen Tutorial wird erläutert, wie Sie mit Visual Studio eine neue WPF-App (Windows Presentation Foundation) erstellen. Nachdem Sie die vorläufige App generiert haben, erfahren Sie, wie Sie Steuerelemente hinzufügen und Ereignisse verarbeiten. Am Ende dieses Tutorials verfügen Sie über eine einfache App, die einem Listenfeld Namen hinzufügt.

Wichtig

Die Dokumentation zum Desktopleitfaden für .NET 6 und .NET 5 (einschließlich .NET Core 3.1) wird derzeit erstellt.

In diesem Tutorial lernen Sie Folgendes:

  • Erstellen einer neuen WPF-App
  • Hinzufügen von Steuerelementen zu einem Formular
  • Verarbeiten von Steuerungsereignissen zum Bereitstellen von App-Funktionalität
  • Ausführen der App

Hier sehen Sie eine Vorschau der App, die Sie im Laufe dieses Tutorials erstellen:

Finished sample app for WPF tutorial

Voraussetzungen

Erstellen einer WPF-App

Für die Erstellung einer neuen App müssen Sie erst Visual Studio öffnen und die App dann aus einer Vorlage erstellen.

  1. Öffnen Sie Visual Studio.

  2. Wählen Sie Neues Projekt erstellen aus.

    Create a new WPF project in Visual Studio 2019 for .NET.

  3. Geben Sie in das Feld Nach Vorlagen suchenwpf ein, und drücken Sie die EINGABETASTE.

  4. Wählen Sie aus der Dropdownliste Codesprache die Option C# oder Visual Basic aus.

  5. Wählen Sie aus der Vorlagenliste WPF-Anwendung aus, und wählen Sie dann Weiter aus.

    Wichtig

    Wählen Sie nicht die Vorlage WPF-Anwendung (.NET Framework) aus.

    Search for the WPF template in Visual Studio 2019 for .NET.

  6. Gehen Sie im Fenster Neues Projekt konfigurieren folgendermaßen vor:

    1. Geben Sie Names im Feld Projektname ein.
    2. Aktivieren Sie das Kontrollkästchen Legen Sie die Projektmappe und das Projekt im selben Verzeichnis ab.
    3. Wählen Sie optional einen anderen Speicherort für Ihren Code aus.
    4. Wählen Sie die Schaltfläche Weiter aus.

    Configure new WPF project in Visual Studio 2019 for .NET

  7. Wählen Sie im Fenster Zusätzliche Informationen im Feld Zielframework die Option .NET 5.0 (aktuell) aus. Wählen Sie die Schaltfläche Erstellen.

    Select target framework for new WPF project in Visual Studio 2019 for .NET

  1. Öffnen Sie Visual Studio.

  2. Wählen Sie Neues Projekt erstellen aus.

    Create a new WPF project in Visual Studio 2022 for .NET.

  3. Geben Sie in das Feld Nach Vorlagen suchenwpf ein, und drücken Sie die EINGABETASTE.

  4. Wählen Sie aus der Dropdownliste Codesprache die Option C# oder Visual Basic aus.

  5. Wählen Sie aus der Vorlagenliste WPF-Anwendung aus, und wählen Sie dann Weiter aus.

    Wichtig

    Wählen Sie nicht die Vorlage WPF-Anwendung (.NET Framework) aus.

    Die folgende Abbildung zeigt Projektvorlagen für C# und Visual Basic .NET. Wenn Sie den Filter Codesprache angewendet haben, wird die entsprechende Vorlage angezeigt.

    Search for the WPF template in Visual Studio 2022 for .NET.

  6. Gehen Sie im Fenster Neues Projekt konfigurieren folgendermaßen vor:

    1. Geben Sie Names im Feld Projektname ein.
    2. Aktivieren Sie das Kontrollkästchen Legen Sie die Projektmappe und das Projekt im selben Verzeichnis ab.
    3. Wählen Sie optional einen anderen Speicherort für Ihren Code aus.
    4. Wählen Sie die Schaltfläche Weiter aus.

    Configure new WPF project in Visual Studio 2022 for .NET

  7. Wählen Sie im Fenster Zusätzliche Informationen im Feld Zielframework die Option .NET 6.0 (langfristiger Support) aus. Wählen Sie die Schaltfläche Erstellen.

    Select target framework for new WPF project in Visual Studio 2022 for .NET

Nachdem die App generiert wurde, sollte Visual Studio den XAML-Designer für das Standardfenster MainWindow öffnen. Wenn der Designer nicht angezeigt wird, doppelklicken Sie im Bereich Projektmappen-Explorer auf die Datei MainWindow.xaml, um den Designer zu öffnen.

Wichtige Visual Studio-Komponenten

WPF wird in Visual Studio durch fünf wichtige Komponenten unterstützt, mit denen Sie bei der App-Erstellung interagieren:

The important components of Visual Studio you should know when creating a WPF project for .NET

The important components of Visual Studio you should know when creating a WPF project for .NET

  1. Projektmappen-Explorer

    Alle Ihre Projektdateien, Fenster und Ressourcen sowie Ihr gesamter Code werden in diesem Bereich angezeigt.

  2. Eigenschaften

    In diesem Bereich werden die Eigenschafteneinstellungen angezeigt, die Sie für das ausgewählte Element konfigurieren können. Wenn Sie z. B. ein Element im Projektmappen-Explorer auswählen, werden die Eigenschafteneinstellungen für diese Datei angezeigt. Wenn Sie ein Objekt im Designer auswählen, werden die Einstellungen für dieses Element angezeigt.

  3. Werkzeugkasten

    Die Toolbox enthält alle Steuerelemente, die Sie einem Formular hinzufügen können. Doppelklicken Sie zum Hinzufügen eines Steuerelements zum aktuellen Formular auf ein Steuerelement, oder verschieben Sie das Steuerelement per Drag & Drop.

  4. XAML-Designer

    Dieser Designer wird für XAML-Dokumente verwendet. Hierbei handelt es sich um eine interaktive Oberfläche, in die Sie Objekte per Drag & Drop aus der Toolbox verschieben können. Wenn Sie Elemente im Designer auswählen und verschieben, können Sie die Benutzeroberfläche für Ihre App visuell zusammenstellen.

    Wenn der Designer und der Editor geöffnet sind, werden Änderungen in einem Bereich auch im anderen übernommen. Wenn Sie Elemente im Designer auswählen, werden im Bereich Eigenschaften die Eigenschaften und Attribute zu diesen Objekten angezeigt.

  5. XAML-Code-Editor

    Dieser XAML-Code-Editor wird für XAML-Dokumente verwendet. Mit dem XAML-Code-Editor können Sie die Benutzeroberfläche selbst erstellen – ganz ohne Designer. Der Designer kann die Werte der Eigenschaften eines Steuerelements ableiten, wenn dieses hinzugefügt wird. Der XAML-Code-Editor bietet Ihnen viel mehr Kontrolle.

    Wenn der Designer und der Editor geöffnet sind, werden Änderungen in einem Bereich auch im anderen übernommen. Wenn Sie mit dem Textcursor im Code-Editor navigieren, werden im Bereich Eigenschaften die Eigenschaften und Attribute zu Objekten angezeigt.

Erläuterungen zum XAML-Code

Nach der Projekterstellung wird der XAML-Code-Editor geöffnet. Er enthält nur den XAML-Code, der zum Anzeigen des Fensters benötigt wird. Wenn der Editor nicht geöffnet wird, doppelklicken Sie im Projektmappen-Explorer auf die Datei MainWindow.xaml. Der XAML-Code sollte folgendem Beispiel entsprechen:

<Window x:Class="Names.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Names"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>

    </Grid>
</Window>

Im Folgenden wird dieser XAML-Code detailliert erläutert. Bei XAML-Code handelt es sich im Prinzip um XML-Code, der von WPF-Compilern verarbeitet werden kann. Er beschreibt die WPF-Benutzeroberfläche und interagiert mit .NET-Code. Sie sollten mindestens mit den Grundlagen zu XML vertraut sein, um den XAML-Code zu verstehen.

Der Dokumentstamm <Window> stellt den Objekttyp dar, der von der XAML-Datei beschrieben wird. In diesem Fall sind acht Attribute deklariert, die in der Regel in eine der folgenden drei Kategorien fallen:

  • Namespaces

    Ein XML-Namespace stellt die Struktur für die XML-Datei bereit, indem er festlegt, welche XML-Inhalte in der Datei deklariert werden können.

    Das Hauptattribut xmlns importiert den XML-Namespace für die gesamte Datei. In diesem Fall ordnet sie diesen zudem den Typen zu, die von WPF deklariert wurden. Die anderen XML-Namespaces deklarieren ein Präfix und importieren andere Typen und Objekte für die XAML-Datei. Der Namespace xmlns:local deklariert beispielsweise das Präfix local und ordnet die von Ihrem Projekt im Codenamespace Names deklarierten Objekte zu.

  • x:Class-Attribut

    Dieses Attribut ordnet <Window> dem Typ zu, der durch Ihren Code definiert wird: die Datei MainWindow.xaml.cs oder MainWindow.xaml.vb, die der Klasse Names.MainWindow entspricht.

  • Title-Attribut

    Jedes normale Attribut, das für ein XAML-Objekt deklariert ist, legt eine Eigenschaft dieses Objekts fest. In diesem Fall legt das Attribut Title die Eigenschaft Window.Title fest.

Ändern des Fensters

Führen Sie zuerst das Projekt aus, und sehen Sie sich die Standardausgabe an. Sie sehen, dass ein Fenster ohne Steuerelemente geöffnet wird, das den Titel MainWindow trägt:

A blank WPF app

Für unsere Beispiel-App ist das Fenster zu groß, und die Titelleiste ist nicht aussagekräftig. Ändern Sie den Titel und die Größe des Fensters, indem Sie die entsprechenden Attribute in der XAML-Datei in die folgenden Werte ändern:

<Window x:Class="Names.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Names"
        mc:Ignorable="d"
        Title="Names" Height="180" Width="260">
    <Grid>
        
    </Grid>
</Window>

Vorbereiten des Layouts

WPF bietet ein ausgereiftes Layoutsystem mit vielen unterschiedlichen Layoutsteuerelementen. Mit Layoutsteuerelementen können die Position und die Größe untergeordneter Steuerelemente geändert werden – und das sogar automatisch. In dieser XAML-Datei wird das Standard-Layoutsteuerelement <Grid> bereitgestellt.

Mit dem Steuerelement Grid können Sie Zeilen und Spalten wie bei einer Tabelle definieren und Steuerelemente innerhalb der Grenzen einer bestimmten Zeilen- und Spaltenkombination platzieren. Sie können eine beliebige Anzahl untergeordneter Steuerelemente oder anderer Layoutsteuerelemente zu Grid hinzufügen. Sie können beispielsweise ein weiteres Grid-Steuerelement in einer bestimmten Zeilen- und Spaltenkombination platzieren. Dieses neue Grid-Element kann dann weitere Zeilen und Spalten definieren und eigene untergeordnete Elemente besitzen.

Das Steuerelement <Grid> definiert die Zeilen und Spalten, in denen sich Ihre Steuerelemente befinden sollen. Für ein Raster ist immer jeweils eine Zeile und eine Spalte deklariert. Das bedeutet, dass ein Raster standardmäßig eine Zelle ist. Das bietet Ihnen nicht viel Flexibilität beim Platzieren der Steuerelemente.

Bevor Sie neue Zeilen und Spalten hinzufügen, sollten Sie ein neues Attribut zum Element <Grid> hinzufügen: Margin="10". Dadurch entsteht ein Abstand zwischen Raster und Fenster, der die Darstellung verbessert.

Definieren Sie als Nächstes zwei Zeilen und zwei Spalten, um das Raster in vier Zellen zu unterteilen:

<Window x:Class="Names.LayoutStep2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Names"
        mc:Ignorable="d"
        Title="Names" Height="180" Width="260">
    <Grid Margin="10">
        
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        
    </Grid>
</Window>

Wählen Sie das Raster im XAML-Code-Editor oder im XAML-Designer aus. Sie sehen, dass der XAML-Designer jede Zeile und Spalte anzeigt:

A WPF app with the margin set on a grid

Hinzufügen des ersten Steuerelements

Nachdem das Raster erstellt wurde, können Sie damit beginnen, Steuerelemente hinzuzufügen. Beginnen Sie mit dem Label-Steuerelement. Erstellen Sie das neue Element <Label> nach den Zeilen- und Spaltendefinitionen im Element <Grid>, und legen Sie den Zeichenfolgenwert Names fest:

<Grid Margin="10">

    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Label>Names</Label>

</Grid>

Das Element <Label>Names</Label> definiert den Inhalt von Names. Manche Steuerelemente können Inhalt verarbeiten, andere nicht. Der Inhalt eines Steuerelements wird der Eigenschaft Content zugeordnet. Verwenden Sie das folgende Format, um den Inhalt über die XAML-Attributsyntax festzulegen: <Label Content="Names" />. Mit beiden Methoden wird der Inhalt der Bezeichnung so festgelegt, dass der Text Names angezeigt wird.

Es gibt jedoch ein Problem: Die Bezeichnung nimmt die Hälfte des Fensters ein, da sie automatisch der ersten Zeile und Spalte des Rasters zugewiesen wurde. Für die erste Zeile wird jedoch nicht so viel Platz benötigt, da diese nur für die Bezeichnung verwendet wird. Ändern Sie das Attribut Height des ersten <RowDefinition>-Elements von * in Auto. Der Wert Auto passt die Größe der Rasterzeile automatisch an den Inhalt an – in diesem Fall an das Label-Steuerelement.

<Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
</Grid.RowDefinitions>

Jetzt sehen Sie, dass die Bezeichnung im Designer nur noch einen geringen Anteil der verfügbaren Höhe einnimmt. So bleibt mehr Platz für die nächste Zeile. Die meisten Steuerelemente definieren einen Wert für die Höhe und Breite, die sie idealerweise einnehmen. Im Fall des Label-Steuerelements ist ein Wert für die Höhe festgelegt, der sicherstellt, dass der Inhalt lesbar ist.

A WPF app with the margin set on a grid and a label control in the first row

Platzierung von Steuerelementen

Nun wird näher auf das Platzieren von Steuerelementen eingegangen. Die im vorherigen Abschnitt erstellte Bezeichnung wurde automatisch in Zeile 0 und Spalte 0 des Rasters platziert. Die Nummerierung für Zeilen und Spalten beginnt bei 0 und wird für jede neue Zeile oder Spalte um 1 erhöht. Das Steuerelement kennt die Eigenschaften des Rasters nicht und definiert keine Eigenschaften, um seine Position im Raster zu steuern. Das Steuerelement hätte sogar in einem anderen Layoutsteuerelement platziert werden können, für das eigene Regeln für die Platzierung von Steuerelementen definiert wurden.

Doch wie weisen Sie ein Steuerelement an, eine andere Zeile und/oder Spalte zu verwenden, wenn es die Eigenschaften des Rasters nicht kennt? Die Antwort lautet: durch angefügte Eigenschaften. Das Raster nutzt das ausgereifte Eigenschaftensystem von WPF. Es definiert neue Eigenschaften, die untergeordnete Steuerelemente deklarieren und verwenden können. Die Eigenschaften sind dabei nicht im Steuerelement selbst vorhanden, sondern werden vom Raster angefügt, wenn das Steuerelement diesem hinzugefügt wird.

Das Raster definiert zwei Eigenschaften, um die Zeilen- und Spaltenposition eines untergeordneten Steuerelements zu bestimmen: Grid.Row und Grid.Column. Wenn diese Eigenschaften im Steuerelement ausgelassen werden, wird impliziert, dass diese den Standardwert 0 aufweisen. Das Steuerelement wird also in Zeile 0 und Spalte 0 des Rasters platziert. Ändern Sie die Position des Steuerelements <Label>, indem Sie das Attribut Grid.Column auf 1 festlegen:

<Label Grid.Column="1">Names</Label>

Sie sehen, dass Ihre Bezeichnung jetzt in die zweite Spalte verschoben wurde. Sie können die angefügten Eigenschaften Grid.Row und Grid.Column verwenden, um die Steuerelemente zu platzieren, die Sie als Nächstes erstellen. Legen Sie vorerst jedoch wieder Zeile 0 für die Bezeichnung fest.

Erstellen eines Listenfelds für Namen

Da die Größe des Rasters jetzt passend eingestellt und die Bezeichnung erstellt wurde, können Sie ein Listenfeld-Steuerelement zur Zeile unter der Bezeichnung hinzufügen. Das Listenfeld wird zu Zeile 1 und Spalte 0 hinzugefügt. Legen Sie für dieses Steuerelement den Namen lstNames fest. Sobald ein Name für ein Steuerelement festgelegt wurde, kann in der CodeBehind-Datei darauf verwiesen werden. Der Name wird dem Steuerelement mit dem Attribut x:Name zugewiesen.

<Grid Margin="10">

    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Label>Names</Label>
    <ListBox Grid.Row="1" x:Name="lstNames" />

</Grid>

Hinzufügen der restlichen Steuerelemente

Sie fügen nun noch zwei weitere Steuerelemente hinzu: ein Textfeld und eine Schaltfläche. Diese werden vom Benutzer verwendet, um einen Namen einzugeben, der dem Listenfeld hinzugefügt wird. Jedoch sollen nun keine weiteren Zeilen und Spalten im Raster erstellt werden. Fügen Sie diese Steuerelemente stattdessen dem Layoutsteuerelement <StackPanel> hinzu.

Das StackPanel-Element unterscheidet sich vom Raster hinsichtlich der Platzierung der Steuerelemente. Während Sie dem Raster mithilfe der angefügten Eigenschaften Grid.Row und Grid.Column mitteilen, wo sich die Steuerelemente befinden sollen, platziert das StackPanel-Element die Steuerelemente automatisch der Reihenfolge nach, bis alle Steuerelemente platziert wurden. Es stapelt die Steuerelemente sozusagen untereinander.

Erstellen Sie das Steuerelement <StackPanel> nach dem Listenfeld, und fügen Sie es in Zeile 1 und Spalte 1 des Rasters ein. Fügen Sie ein weiteres Attribut namens Margin mit dem Wert 5,0,0,0 hinzu:

<Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
    <ColumnDefinition Width="*" />
    <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<Label>Names</Label>
<ListBox Grid.Row="1" x:Name="lstNames" />

<StackPanel Grid.Row="1" Grid.Column="1" Margin="5,0,0,0">
    
</StackPanel>

Das Attribut Margin wurde zuvor im Raster verwendet. Sie haben jedoch nur den Wert 10 angegeben. Jetzt wird der Wert 5,0,0,0 im StackPanel-Element verwendet. Der Rand ist ein Thickness-Typ und kann daher beide Werte interpretieren. Ein solcher Typ definiert den Leerraum um jede Seite eines rechteckigen Rahmens: links, oben, rechts, unten. Wenn nur ein Wert für den Rand vorhanden ist, wird dieser für alle vier Seiten verwendet.

Erstellen Sie als Nächstes ein <TextBox>- und ein <Button>-Steuerelement im <StackPanel>-Element.

<StackPanel Grid.Row="1" Grid.Column="1" Margin="5,0,0,0">
    <TextBox x:Name="txtName" />
    <Button x:Name="btnAdd" Margin="0,5,0,0">Add Name</Button>
</StackPanel>

Das Layout für das Fenster ist damit fertig. Ihre App enthält jedoch noch keine Logik und ist damit nicht funktional. Als Nächstes müssen Sie die Steuerelementereignisse mit dem Code verbinden, damit die App eine Funktion erfüllt.

Hinzufügen von Code für ein Click-Ereignis

Das erstellte <Button>-Element enthält das Ereignis Click, das immer dann ausgelöst wird, wenn der Benutzer eine Schaltfläche auswählt. Sie können dieses Ereignis abonnieren und Code hinzufügen, um dem Listenfeld einen Namen hinzuzufügen. Genau wie Sie eine Eigenschaft in einem Steuerelement festlegen, indem Sie ein XAML-Attribut festlegen, können Sie ein XAML-Attribut auch verwenden, um ein Ereignis zu abonnieren. Legen Sie das Click-Attribut auf ButtonAddName_Click fest.

<StackPanel Grid.Row="1" Grid.Column="1" Margin="5,0,0,0">
    <TextBox x:Name="txtName" />
    <Button x:Name="btnAdd" Margin="0,5,0,0" Click="ButtonAddName_Click">Add Name</Button>
</StackPanel>

Nun müssen Sie den Handlercode generieren. Klicken Sie mit der rechten Maustaste auf ButtonAddName_Click, und wählen Sie Gehe zu Definition aus. Diese Aktion erstellt eine Methode in der CodeBehind-Datei, die mit dem eingegebenen Handlernamen übereinstimmt.

private void ButtonAddName_Click(object sender, RoutedEventArgs e)
{

}
Private Sub ButtonAddName_Click(sender As Object, e As RoutedEventArgs)

End Sub

Fügen Sie als Nächstes den folgenden Code hinzu, um diese drei Schritte auszuführen:

  1. Sicherstellen, dass das Textfeld einen Namen enthält
  2. Überprüfen, ob der in das Textfeld eingegebene Name bereits vorhanden ist
  3. Hinzufügen des Namens zum Listenfeld
private void ButtonAddName_Click(object sender, RoutedEventArgs e)
{
    if (!string.IsNullOrWhiteSpace(txtName.Text) && !lstNames.Items.Contains(txtName.Text))
    {
        lstNames.Items.Add(txtName.Text);
        txtName.Clear();
    }
}
Private Sub ButtonAddName_Click(sender As Object, e As RoutedEventArgs)
    If Not String.IsNullOrWhiteSpace(txtName.Text) And Not lstNames.Items.Contains(txtName.Text) Then
        lstNames.Items.Add(txtName.Text)
        txtName.Clear()
    End If
End Sub

Ausführen der App

Nachdem das Ereignis programmiert wurde, können Sie die App ausführen, indem Sie auf F5 drücken oder im Menü auf Debuggen>Debuggen starten klicken. Das Fenster wird angezeigt, und Sie können einen Namen in das Textfeld eingeben und diesen durch Auswählen der Schaltfläche hinzufügen.

Running a Windows Presentation Foundation (WPF) for .NET app.

Nächste Schritte