Zelfstudie: Een nieuwe WPF-app maken met .NET
In deze zelfstudie leert u hoe u Visual Studio gebruikt om een nieuwe WPF-app (Windows Presentation Foundation) te maken. Met Visual Studio voegt u besturingselementen toe aan vensters om de gebruikersinterface van de app te ontwerpen en verwerkt u invoerevenementen van deze besturingselementen om met de gebruiker te communiceren. Aan het einde van deze zelfstudie hebt u een eenvoudige app waarmee namen aan een keuzelijst worden toegevoegd.
In deze zelfstudie gaat u het volgende doen:
- Maak een nieuwe WPF-app.
- Besturingselementen toevoegen aan een venster.
- Beheer besturingsevenementen om de functionaliteit van de app te bieden.
- Voer de app uit.
Hier volgt een voorbeeld van de app die is gemaakt tijdens deze zelfstudie:
Voorwaarden
Voorzichtigheid
.NET 6 wordt niet meer ondersteund. Het is raadzaam om .NET 9.0 te gebruiken.
-
Visual Studio 2022 versie 17.0 of hoger
- Selecteer de workload voor het ontwikkelen van .NET-desktops
- Selecteer het afzonderlijke onderdeel .NET 6
Voorzichtigheid
.NET 7 wordt niet meer ondersteund. Het is raadzaam om .NET 9.0 te gebruiken.
-
Visual Studio 2022 versie 17.4 of hoger
- Selecteer de workload voor het ontwikkelen van .NET-desktops
- Selecteer het .NET 7 afzonderlijke onderdeel
-
Visual Studio 2022 versie 17.8 of hoger
- Selecteer de workload voor het ontwikkelen van .NET-desktops
- Selecteer het afzonderlijke onderdeel .NET 8
-
Visual Studio 2022 versie 17.12 of hoger
- Selecteer de workload voor het ontwikkelen van .NET-desktops
- Selecteer het afzonderlijke onderdeel .NET 9
Een WPF-app maken
De eerste stap bij het maken van een nieuwe app is het openen van Visual Studio en het genereren van de app op basis van een sjabloon.
Open Visual Studio.
Selecteer Een nieuw project maken.
Typ wpfin het vak Zoeken naar sjablonen en druk vervolgens op Enter.
Kies in het dropdownmenu voor de codetaal C# of Visual Basic.
Selecteer in de lijst met sjablonen WPF-toepassing en selecteer vervolgens Volgende.
Belangrijk
Selecteer niet het WPF-toepassing (.NET Framework) sjabloon.
In de volgende afbeelding ziet u zowel C# als Visual Basic .NET-projectsjablonen. Als u de codetaal filter hebt toegepast, wordt alleen de sjabloon voor die taal weergegeven.
Ga als volgt te werk in het venster Uw nieuwe project configureren:
- Voer in het vak ProjectnaamNamenin.
- Selecteer het selectievakje Plaats oplossing en project in dezelfde map.
- Kies desgewenst een andere Locatie om uw code op te slaan.
- Selecteer de knop Volgende.
Selecteer in het venster Aanvullende informatie.NET 6.0 (langetermijnondersteuning) voor Target Framework-. Selecteer de knop maken.
Open Visual Studio.
Selecteer Een nieuw project maken.
Typ wpfin het vak Zoeken naar sjablonen en druk vervolgens op Enter.
Kies in het dropdownmenu voor de codetaal C# of Visual Basic.
Selecteer in de lijst met sjablonen WPF-toepassing en selecteer vervolgens Volgende.
Belangrijk
Selecteer niet het WPF-toepassing (.NET Framework) sjabloon.
In de volgende afbeelding ziet u zowel C# als Visual Basic .NET-projectsjablonen. Als u de codetaal filter hebt toegepast, wordt alleen de sjabloon voor die taal weergegeven.
Ga als volgt te werk in het venster Uw nieuwe project configureren:
- Voer in het vak ProjectnaamNamenin.
- Selecteer het selectievakje Plaats oplossing en project in dezelfde map.
- Kies desgewenst een andere Locatie om uw code op te slaan.
- Selecteer de knop Volgende.
Selecteer in het venster Aanvullende informatie de optie .NET 7.0 (Standaard Termijnondersteuning) voor het Target Framework. Selecteer de knop maken.
Open Visual Studio.
Selecteer Een nieuw project maken.
Typ wpfin het vak Zoeken naar sjablonen en druk vervolgens op Enter.
Kies in het dropdownmenu voor de codetaal C# of Visual Basic.
Selecteer in de lijst met sjablonen WPF-toepassing en selecteer vervolgens Volgende.
Belangrijk
Selecteer niet het WPF-toepassing (.NET Framework) sjabloon.
In de volgende afbeelding ziet u zowel C# als Visual Basic .NET-projectsjablonen. Als u de codetaal filter hebt toegepast, wordt alleen de sjabloon voor die taal weergegeven.
Ga als volgt te werk in het venster Uw nieuwe project configureren:
- Voer in het vak ProjectnaamNamenin.
- Selecteer het selectievakje Plaats oplossing en project in dezelfde map.
- Kies desgewenst een andere Locatie om uw code op te slaan.
- Selecteer de knop Volgende.
Selecteer in het venster Aanvullende informatie.NET 8.0 (Long Term Support) voor Target Framework. Selecteer de knop maken.
Open Visual Studio.
Selecteer Een nieuw project maken.
Typ wpfin het vak Zoeken naar sjablonen en druk vervolgens op Enter.
Kies in het dropdownmenu voor de codetaal C# of Visual Basic.
Selecteer in de lijst met sjablonen WPF-toepassing en selecteer vervolgens Volgende.
Belangrijk
Selecteer niet het WPF-toepassing (.NET Framework) sjabloon.
In de volgende afbeelding ziet u zowel C# als Visual Basic .NET-projectsjablonen. Als u de codetaal filter hebt toegepast, wordt alleen de sjabloon voor die taal weergegeven.
Ga als volgt te werk in het venster Uw nieuwe project configureren:
- Voer in het vak ProjectnaamNamenin.
- Selecteer het selectievakje Plaats oplossing en project in dezelfde map.
- Kies desgewenst een andere Locatie om uw code op te slaan.
- Selecteer de knop Volgende.
In het venster Aanvullende informatie selecteer je .NET 9.0 (Standard Term Support) voor Target Framework. Selecteer de knop maken.
Zodra de app is gegenereerd, moet Visual Studio het XAML-ontwerpvenster openen voor het standaardvenster, MainWindow. Als de ontwerper niet zichtbaar is, dubbelklikt u op het bestand MainWindow.xaml in het Solution Explorer venster om de ontwerpfunctie te openen.
Belangrijke onderdelen van Visual Studio
Ondersteuning voor WPF in Visual Studio heeft vijf belangrijke onderdelen waarmee u werkt wanneer u een app maakt:
Solution Explorer
Al uw projectbestanden, code, vensters, resources, worden weergegeven in dit venster.
Eigenschappen
In dit venster worden eigenschapsinstellingen weergegeven die u kunt configureren op basis van het geselecteerde item. Als u bijvoorbeeld een item selecteert in Solution Explorer, ziet u eigenschapsinstellingen met betrekking tot het bestand. Als u een object selecteert in de Designer-, ziet u instellingen voor het element. Met betrekking tot de vorige afbeelding is de titelbalk van het venster geselecteerd in de ontwerpfunctie.
Gereedschapskist
De werkset bevat alle besturingselementen die u aan een ontwerpoppervlak kunt toevoegen. Als u een besturingselement wilt toevoegen aan het huidige oppervlak, dubbelklikt u op het besturingselement of sleept u het besturingselement neer op het oppervlak. Het is gebruikelijk om in plaats daarvan het venster van de XAML-code-editor te gebruiken om een gebruikersinterface (UI) te ontwerpen, terwijl u het XAML-ontwerpvenster gebruikt om een voorbeeld van de resultaten te bekijken.
XAML-ontwerper
Dit is de ontwerpfunctie voor een XAML-document. Het is interactief en u kunt objecten slepen en neerzetten vanuit de Werkset. Door items in de ontwerpfunctie te selecteren en te verplaatsen, kunt u de gebruikersinterface voor uw app visueel samenstellen.
Wanneer zowel de ontwerpfunctie als de editor zichtbaar zijn, worden wijzigingen in de ene weergegeven in de andere.
Wanneer u items in de ontwerpfunctie selecteert, worden in het venster Eigenschappen de eigenschappen en kenmerken van dat object weergegeven.
XAML-code-editor
Dit is de XAML-code-editor voor een XAML-document. De XAML-code-editor is een manier om uw gebruikersinterface handmatig te maken zonder een ontwerper. De ontwerper kan automatisch eigenschappen instellen voor een besturingselement wanneer het besturingselement wordt toegevoegd in de ontwerpfunctie. De XAML-code-editor biedt u veel meer controle.
Wanneer zowel de ontwerpfunctie als de editor zichtbaar zijn, worden wijzigingen in de ene weergegeven in de andere. Terwijl u door de tekstverzorging in de code-editor navigeert, worden in het venster Eigenschappen de eigenschappen en kenmerken van dat object weergegeven.
De XAML onderzoeken
Nadat uw project is gemaakt, is de XAML-code-editor zichtbaar met een minimale hoeveelheid XAML-code om het venster weer te geven. Als de editor niet is geopend, dubbelklik op MainWindow.xaml in het venster Solution Explorer. XAML moet er ongeveer uitzien als in het volgende voorbeeld:
<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>
Belangrijk
Als u codeert in Visual Basic, is de XAML iets anders, met name het kenmerk x:Class=".."
. XAML in Visual Basic gebruikt de klassenaam van het object en laat de naamruimte van de klasse weg.
Laten we de XAML opsplitsen om meer inzicht te krijgen in de XAML. XAML is gewoon XML die door WPF wordt verwerkt om een gebruikersinterface te maken. Als u XAML wilt begrijpen, moet u minimaal bekend zijn met de basisbeginselen van XML.
De document root <Window>
vertegenwoordigt het type object dat wordt beschreven door het XAML-document. Er zijn acht kenmerken gedeclareerd en ze behoren over het algemeen tot drie categorieën:
XML-naamruimten
Een XML-naamruimte biedt structuur aan de XML en bepaalt welke XML-inhoud in het bestand kan worden gedeclareerd.
Het belangrijkste
xmlns
-attribuut importeert de XML-naamruimte voor het hele bestand en wordt in dit geval toegewezen aan de typen die door WPF zijn gedeclareerd. De andere XML-naamruimten declareren een voorvoegsel en importeren andere typen en objecten voor het XAML-bestand. Dexmlns:local
naamruimte declareert bijvoorbeeld hetlocal
voorvoegsel en wijst toe aan de objecten die door uw project zijn gedeclareerd, de objecten die zijn gedeclareerd in deNames
codenaamruimte.kenmerk
x:Class
Dit kenmerk wijst de
<Window>
toe aan het type dat is gedefinieerd door uw code: het MainWindow.xaml.cs- of MainWindow.xaml.vb-bestand. Dit is deNames.MainWindow
klasse in C# enMainWindow
in Visual Basic.kenmerk
Title
Elk normaal kenmerk dat is gedeclareerd op het XAML-object, stelt een eigenschap van dat object in. In dit geval wordt met het kenmerk
Title
de eigenschapWindow.Title
ingesteld.
Het venster wijzigen
Voor onze voorbeeld-app is dit venster te groot en is de titelbalk niet beschrijvend. Laten we dat oplossen.
Voer eerst de app uit door op de toets F5 te drukken of door Foutopsporing>Start Debugging te selecteren in het menu.
U ziet het standaardvenster dat door de sjabloon wordt gegenereerd, zonder bedieningsonderdelen, en met de titel MainWindow:
Wijzig de titel van het venster door de
Title
in te stellen opNames
.Wijzig de grootte van het venster door de
Height
in te stellen op180
enWidth
op260
.<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>
De indeling voorbereiden
WPF biedt een krachtig indelingssysteem met veel verschillende indelingsbesturingselementen. Indelingsbesturingselementen helpen om kindbesturingselementen te plaatsen en de grootte ervan te wijzigen, en kunnen dit zelfs automatisch doen. Het standaardindelingselement dat aan u in deze XAML is geleverd, is besturingselement <Grid>
.
Met het rasterbesturingselement kunt u rijen en kolommen definiëren, net zoals een tabel, en besturingselementen binnen de grenzen van een specifieke rij- en kolomcombinatie plaatsen. U kunt een willekeurig aantal kindobjecten of andere layoutelementen aan het raster toevoegen. U kunt bijvoorbeeld een ander <Grid>
controle-element in een specifieke rij- en kolomcombinatie plaatsen, waarna dat nieuwe raster vervolgens meer rijen en kolommen kan definiëren en zijn eigen onderliggende elementen kan bevatten.
Het rasterbesturingselement plaatst de onderliggende besturingselementen in rijen en kolommen. Een raster heeft altijd één rij en kolom gedeclareerd, wat betekent dat het raster standaard één cel is. Dat geeft u niet echt veel flexibiliteit bij het plaatsen van besturingselementen.
Pas de rasterindeling aan voor de bedieningselementen die vereist zijn voor deze app.
Voeg een nieuw kenmerk toe aan het
<Grid>
-element:Margin="10"
.Deze instelling brengt het raster van de vensterranden binnen en maakt het een beetje mooier.
Definieer twee rijen en twee kolommen, waarbij het raster wordt verdeeld in vier cellen:
<Grid Margin="10"> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> </Grid>
Selecteer het raster in de XAML-code-editor of XAML-ontwerper. U ziet dat de XAML-ontwerper elke rij en kolom weergeeft:
Het eerste besturingselement toevoegen
Nu het raster is geconfigureerd, kunnen we er bedieningselementen aan toevoegen. Begin eerst met de labelcontrole.
Maak een nieuw
<Label>
element in het<Grid>
element, na de rij- en kolomdefinities. Stel de inhoud van het element in op de tekenreekswaarde vanNames
:<Grid Margin="10"> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Label>Names</Label> </Grid>
De
<Label>Names</Label>
definieert de inhoudNames
. Sommige besturingselementen begrijpen hoe inhoud moet worden verwerkt, andere niet. De inhoud van een besturingselement wordt toegewezen aan de eigenschapContent
. Als u de inhoud instelt via de syntaxis van het XAML-kenmerk, gebruikt u deze indeling:<Label Content="Names" />
. Beide manieren doen hetzelfde, waarbij de inhoud van het label wordt ingesteld om de tekst weer te gevenNames
.U ziet dat het label de helft van het venster in beslag neemt, omdat het automatisch is geplaatst in de eerste rij en kolom van het raster. Voor onze eerste rij hebben we niet zoveel ruimte nodig omdat we die rij alleen gebruiken voor het label.
Wijzig het kenmerk
Height
van de eerste<RowDefinition>
van*
inAuto
.De
Auto
-waarde bepaalt de grootte van de rasterrij automatisch op de grootte van de inhoud, in dit geval de labelcontrole.<Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions>
U ziet dat de ontwerper nu toont dat het label een kleine hoeveelheid van de beschikbare hoogte in beslag neemt. Er is nu meer ruimte beschikbaar voor de volgende rij.
Plaatsing besturingselementen
Laten we het hebben over de plaatsing van bedienings-elementen. Het label dat in de vorige sectie is gemaakt, wordt automatisch in rij 0 en kolom 0 van het raster geplaatst. De nummering voor rijen en kolommen begint bij 0 en wordt met 1 verhoogd. Het besturingselement weet niets van het raster en het besturingselement definieert geen eigenschappen om de plaatsing ervan in het raster te beheren.
Hoe laat u een besturingselement weten dat een andere rij of kolom moet worden gebruikt wanneer het besturingselement geen kennis heeft van het raster? Gekoppelde eigenschappen! Het raster maakt gebruik van het krachtige eigenschappensysteem van WPF.
Het rasterbesturingselement definieert nieuwe eigenschappen die de child controls aan zichzelf kunnen koppelen. De eigenschappen bestaan niet daadwerkelijk op het besturingselement zelf, ze zijn beschikbaar voor het besturingselement zodra het is toegevoegd aan het raster.
Het raster definieert twee eigenschappen om de positie van een onderliggend besturingselement te bepalen: Grid.Row
en Grid.Column
. Als deze eigenschappen worden weggelaten uit het besturingselement, wordt geïmpliceerd dat ze de standaardwaarden 0 hebben, dus wordt het besturingselement in rij 0
en kolom 0
van het raster geplaatst. Wijzig de plaatsing van het besturingselement <Label>
door het kenmerk Grid.Column
in te stellen op 1
:
<Label Grid.Column="1">Names</Label>
U ziet dat het label is verplaatst naar de tweede kolom. U kunt de Grid.Row
en Grid.Column
gekoppelde eigenschappen gebruiken om de volgende besturingselementen die we gaan maken te plaatsen. Voorlopig herstelt u het label echter naar kolom 0.
Maak de namenlijst aan
Nu het raster op de juiste manier is aangepast en het label is gemaakt, voegt u op de rij onder het label een lijstvak toe.
Declareer het besturingselement
<ListBox />
als een sub-element van het besturingselement<Label>
.Stel de eigenschap
Grid.Row
in op1
.Stel de eigenschap
x:Name
in oplstNames
.Zodra een controle een naam heeft, kan er naar worden verwezen in de bijbehorende code. De naam wordt toegewezen aan het besturingselement met het kenmerk
x:Name
.
De XAML moet er als volgt uitzien:
<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>
De resterende besturingselementen toevoegen
De laatste twee besturingselementen die we gaan toevoegen, zijn een tekstvak en een knop, waarin de gebruiker een naam invoert om toe te voegen aan de lijst. In plaats van meer rijen en kolommen in het raster te maken om deze besturingselementen te rangschikken, plaatsen we deze besturingselementen echter in het <StackPanel>
indelingsbesturingselement.
Het stackpaneel verschilt van het raster in de wijze waarop de besturingselementen worden geplaatst. Terwijl u aangeeft waar u de besturingselementen met de gekoppelde eigenschappen Grid.Row
en Grid.Column
wilt hebben, werkt het stapelpaneel automatisch en plaatst elk van zijn kindbesturingselementen in volgorde. Het 'stapelt' elk besturingselement na de andere.
Declareer het besturingselement
<StackPanel>
als een sub-element van het besturingselement<ListBox>
.Stel de eigenschap
Grid.Row
in op1
.Stel de eigenschap
Grid.Column
in op1
.Stel de
Margin
in op5,0,0,0
.<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>
Het kenmerk
Margin
werd eerder in het raster gebruikt, maar we hebben slechts één waarde,10
. Deze marge heeft een waarde van5,0,0,0
, die heel anders is dan10
. De marge-eigenschap is eenThickness
type en kan beide waarden interpreteren. Een dikte definieert de ruimte rond elke zijde van een rechthoekig kader, linker, bovenste, rechts, respectievelijk onderste. Als de waarde voor de marge één waarde is, wordt die waarde voor alle vier de zijden gebruikt.Maak in het besturingselement
<StackPanel>
een<TextBox />
besturingselement.- Stel de eigenschap
x:Name
in optxtName
.
- Stel de eigenschap
Ten slotte maakt u na de
<TextBox>
, nog steeds binnen de<StackPanel>
, een<Button>
controle-element.- Stel de eigenschap
x:Name
in opbtnAdd
. - Stel de
Margin
in op0,5,0,0
. - Stel de inhoud in op
Add Name
.
- Stel de eigenschap
De XAML moet er als volgt uitzien:
<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>
De indeling voor het venster is voltooid. Onze app heeft echter geen logica om daadwerkelijk functioneel te zijn. Vervolgens moeten we de controle-evenementen koppelen aan code en de app daadwerkelijk iets laten doen.
Code toevoegen voor de klik-gebeurtenis
De <Button>
die we hebben gemaakt, heeft een Click
-gebeurtenis die wordt geactiveerd wanneer de gebruiker op de knop drukt. U kunt zich abonneren op deze gebeurtenis en code toevoegen om een naam toe te voegen aan de keuzelijst. XAML-kenmerken worden gebruikt om u te abonneren op gebeurtenissen, net zoals ze worden gebruikt om eigenschappen in te stellen.
Vind het besturingselement
<Button>
.Het kenmerk
Click
instellen opButtonAddName_Click
<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>
Genereer de code van de gebeurtenis-handler. Klik met de rechtermuisknop op
ButtonAddName_Click
en selecteer Ga naar definitie.Met deze actie wordt een methode gegenereerd in de achterliggende code die overeenkomt met de opgegeven handlernaam.
private void ButtonAddName_Click(object sender, RoutedEventArgs e) { }
Private Sub ButtonAddName_Click(sender As Object, e As RoutedEventArgs) End Sub
Voeg vervolgens de volgende code toe om deze drie stappen uit te voeren:
- Zorg ervoor dat het tekstvak een naam bevat.
- Controleer of de naam die in het tekstvak is ingevoerd nog niet bestaat.
- Voeg de naam toe aan de keuzelijst.
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
De app uitvoeren
Nu de gebeurtenis is verwerkt, voert u de app uit. Het venster wordt weergegeven en u kunt een naam invoeren in het tekstvak en deze vervolgens toevoegen door op de knop te klikken.
Verwante inhoud
- Meer informatie over Windows Presentation Foundation
- Overzicht van XAML
.NET Desktop feedback