Samouczek: tworzenie nowej aplikacji WPF przy użyciu platformy .NET
Z tego krótkiego samouczka dowiesz się, jak utworzyć nową aplikację Windows Presentation Foundation (WPF) za pomocą programu Visual Studio. Po wygenerowaniu początkowej aplikacji dowiesz się, jak dodawać kontrolki i jak obsługiwać zdarzenia. Na koniec tego samouczka będziesz mieć prostą aplikację, która dodaje nazwy do pola listy.
Z tego samouczka dowiesz się, jak wykonywać następujące czynności:
- Tworzenie nowej aplikacji WPF
- Dodawanie kontrolek do formularza
- Obsługa zdarzeń sterowania w celu zapewnienia funkcjonalności aplikacji
- Uruchom aplikację
Oto wersja zapoznawcza aplikacji, którą utworzysz, wykonując czynności opisane w tym samouczku:
Wymagania wstępne
Napiwek
Użyj programu Visual Studio 2022 w wersji 17.4 lub nowszej i zainstaluj zarówno poszczególne składniki platformy .NET 7, jak i .NET 6. Dodano obsługę platformy .NET 7 w programie Visual Studio 2022 w wersji 17.4.
Tworzenie aplikacji WPF
Pierwszym krokiem tworzenia nowej aplikacji jest otwarcie programu Visual Studio i wygenerowanie aplikacji na podstawie szablonu.
Otwórz program Visual Studio.
Wybierz pozycję Utwórz nowy projekt.
W polu Wyszukaj szablony wpisz wpf, a następnie naciśnij Enter.
Z listy rozwijanej języka kodu wybierz pozycję C# lub Visual Basic.
Na liście szablonów wybierz pozycję Aplikacja WPF, a następnie wybierz pozycję Dalej.
Ważne
Nie wybieraj szablonu Aplikacja WPF (.NET Framework).
Na poniższej ilustracji przedstawiono zarówno szablony projektów C#, jak i Visual Basic .NET. Jeśli zastosowano filtr języka kodu, zobaczysz odpowiedni szablon.
W oknie Konfigurowanie nowego projektu wykonaj następujące czynności:
- W polu Nazwa projektu wprowadź nazwy.
- Zaznacz pole wyboru Umieść rozwiązanie i projekt w tym samym katalogu.
- Opcjonalnie wybierz inną lokalizację , aby zapisać kod.
- Kliknij przycisk Next (Dalej).
W oknie Dodatkowe informacje wybierz pozycję .NET 6.0 (obsługa długoterminowa) dla platformy docelowej. Zaznacz przycisk Utwórz.
Otwórz program Visual Studio.
Wybierz pozycję Utwórz nowy projekt.
W polu Wyszukaj szablony wpisz wpf, a następnie naciśnij Enter.
Z listy rozwijanej języka kodu wybierz pozycję C# lub Visual Basic.
Na liście szablonów wybierz pozycję Aplikacja WPF, a następnie wybierz pozycję Dalej.
Ważne
Nie wybieraj szablonu Aplikacja WPF (.NET Framework).
Na poniższej ilustracji przedstawiono zarówno szablony projektów C#, jak i Visual Basic .NET. Jeśli zastosowano filtr języka kodu, zobaczysz odpowiedni szablon.
W oknie Konfigurowanie nowego projektu wykonaj następujące czynności:
- W polu Nazwa projektu wprowadź nazwy.
- Zaznacz pole wyboru Umieść rozwiązanie i projekt w tym samym katalogu.
- Opcjonalnie wybierz inną lokalizację , aby zapisać kod.
- Kliknij przycisk Next (Dalej).
W oknie Dodatkowe informacje wybierz pozycję .NET 7.0 (obsługa terminów standardowych) dla platformy docelowej. Zaznacz przycisk Utwórz.
Po wygenerowaniu aplikacji program Visual Studio powinien otworzyć okienko projektanta XAML dla okna domyślnego MainWindow. Jeśli projektant nie jest widoczny, kliknij dwukrotnie plik MainWindow.xaml w okienku Eksplorator rozwiązań, aby otworzyć projektanta.
Ważne części programu Visual Studio
Obsługa platformy WPF w programie Visual Studio ma pięć ważnych składników, z którymi będziesz korzystać podczas tworzenia aplikacji:
Eksplorator rozwiązań
Wszystkie pliki projektu, kod, okna, zasoby zostaną wyświetlone w tym okienku.
Właściwości
W tym okienku przedstawiono ustawienia właściwości, które można skonfigurować na podstawie wybranego elementu. Jeśli na przykład wybierzesz element z Eksplorator rozwiązań, zobaczysz ustawienia właściwości powiązane z plikiem. Jeśli wybierzesz obiekt w Projektancie, zobaczysz ustawienia dla tego elementu.
Przybornik
Przybornik zawiera wszystkie kontrolki, które można dodać do formularza. Aby dodać kontrolkę do bieżącego formularza, kliknij dwukrotnie kontrolkę lub przeciągnij i upuść kontrolkę.
Projektant XAML
Jest to projektant dokumentu XAML. Jest to interaktywne i można przeciągać i upuszczać obiekty z przybornika. Wybierając i przenosząc elementy w projektancie, możesz wizualnie utworzyć interfejs użytkownika dla aplikacji.
Gdy zarówno projektant, jak i edytor są widoczne, zmiany w jednym są odzwierciedlane w drugim. Po wybraniu elementów w projektancie w okienku Właściwości zostaną wyświetlone właściwości i atrybuty dotyczące tego obiektu.
Edytor kodu XAML
Jest to edytor kodu XAML dla dokumentu XAML. Edytor kodu XAML to sposób tworzenia interfejsu użytkownika ręcznie bez projektanta. Projektant może wnioskować wartości właściwości kontrolki po dodaniu kontrolki w projektancie. Edytor kodu XAML zapewnia znacznie większą kontrolę.
Gdy zarówno projektant, jak i edytor są widoczne, zmiany w jednym są odzwierciedlane w drugim. Podczas nawigowania po karetce tekstu w edytorze kodu okienko Właściwości wyświetla właściwości i atrybuty dotyczące tego obiektu.
Sprawdzanie kodu XAML
Po utworzeniu projektu edytor kodu XAML jest widoczny z minimalną ilością kodu XAML do wyświetlenia okna. Jeśli edytor nie jest otwarty, kliknij dwukrotnie element MainWindow.xaml w Eksplorator rozwiązań. Powinien zostać wyświetlony kod XAML podobny do następującego przykładu:
<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>
Przeanalizujmy ten kod XAML, aby lepiej go zrozumieć. XAML jest po prostu XML, który może być przetwarzany przez kompilatory używane przez WPF. Opisuje on interfejs użytkownika platformy WPF i wchodzi w interakcje z kodem platformy .NET. Aby zrozumieć język XAML, należy zapoznać się co najmniej z podstawami kodu XML.
Katalog główny <Window>
dokumentu reprezentuje typ obiektu opisywanego przez plik XAML. Zadeklarowane są osiem atrybutów i zazwyczaj należą do trzech kategorii:
Przestrzenie nazw
Przestrzeń nazw XML zapewnia strukturę xml, określając, jaką zawartość XML można zadeklarować w pliku.
Główny
xmlns
atrybut importuje przestrzeń nazw XML dla całego pliku, a w tym przypadku mapuje na typy zadeklarowane przez WPF. Inne przestrzenie nazw XML deklarują prefiks i importują inne typy i obiekty dla pliku XAML. Na przykładxmlns:local
przestrzeń nazw deklaruje prefiks i mapujelocal
je na obiekty zadeklarowane przez projekt, czyli te zadeklarowane wNames
przestrzeni nazw kodu.Atrybut
x:Class
Ten atrybut mapuje typ
<Window>
zdefiniowany przez kod: plik MainWindow.xaml.cs lub MainWindow.xaml.vb , który jest klasąNames.MainWindow
.Atrybut
Title
Każdy atrybut normalny zadeklarowany w obiekcie XAML ustawia właściwość tego obiektu. W tym przypadku
Title
atrybut ustawiaWindow.Title
właściwość .
Zmienianie okna
Najpierw uruchom projekt i wyświetl domyślne dane wyjściowe. Zobaczysz wyskakujące okno bez żadnych kontrolek i tytuł MainWindow:
W naszej przykładowej aplikacji to okno jest zbyt duże, a pasek tytułu nie jest opisowy. Zmień tytuł i rozmiar okna, zmieniając odpowiednie atrybuty w języku XAML na następujące wartości:
<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>
Przygotowywanie układu
WPF zapewnia zaawansowany system układu z wieloma różnymi kontrolkami układu. Kontrolki układu ułatwiają umieszczanie i ustawianie rozmiaru kontrolek podrzędnych, a nawet mogą to zrobić automatycznie. Domyślna kontrolka układu udostępniona w tym kodzie XAML to kontrolka <Grid>
.
Kontrolka Grid
umożliwia definiowanie wierszy i kolumn, podobnie jak tabela, oraz umieszczanie kontrolek w granicach określonej kombinacji wierszy i kolumn. Możesz mieć dowolną liczbę kontrolek podrzędnych lub innych kontrolek układu dodanych do elementu Grid
. Można na przykład umieścić inną Grid
kontrolkę w określonej kombinacji wierszy i kolumn, a następnie Grid
zdefiniować więcej wierszy i kolumn oraz mieć własne elementy podrzędne.
Kontrolka <Grid>
definiuje wiersze i kolumny, w których będą używane kontrolki. Siatka zawsze ma zadeklarowany pojedynczy wiersz i kolumnę, co oznacza, że siatka domyślnie jest pojedynczą komórką. To naprawdę nie daje dużo elastyczności w umieszczaniu kontrolek.
Przed dodaniem nowych wierszy i kolumn dodaj nowy atrybut do <Grid>
elementu : Margin="10"
. Spowoduje to zaostrzeniu siatki z okna i sprawia, że wygląda trochę ładniej.
Następnie zdefiniuj dwa wiersze i dwie kolumny, dzieląc siatkę na cztery komórki:
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
</Grid>
Wybierz siatkę w edytorze kodu XAML lub projektancie XAML. Zobaczysz, że projektant XAML pokazuje każdy wiersz i kolumnę:
Dodawanie pierwszej kontrolki
Teraz, gdy siatka została utworzona, możemy rozpocząć dodawanie do niej kontrolek. Najpierw zacznij od kontrolki etykiety. Utwórz nowy <Label>
element wewnątrz <Grid>
elementu po definicjach wierszy i kolumn i nadaj mu wartość ciągu :Names
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label>Names</Label>
</Grid>
Element <Label>Names</Label>
definiuje zawartość Names
. Niektóre kontrolki rozumieją sposób obsługi zawartości, inne nie. Zawartość kontrolki mapuje na Content
właściwość . Ustawienie zawartości za pomocą składni atrybutu XAML, należy użyć następującego formatu: <Label Content="Names" />
. Oba sposoby umożliwiają osiągnięcie tego samego celu, ustawiając zawartość etykiety, aby wyświetlić tekst Names
.
Mamy jednak problem, etykieta zajmuje połowę okna, ponieważ został automatycznie przypisany do pierwszego wiersza i kolumny siatki. W naszym pierwszym wierszu nie potrzebujemy tyle miejsca, ponieważ będziemy używać tylko tego wiersza dla etykiety. Height
Zmień atrybut pierwszego <RowDefinition>
elementu z *
na Auto
. Wartość Auto
automatycznie zmienia rozmiar wiersza siatki na rozmiar jego zawartości, w tym przypadku kontrolkę etykiety.
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
Zwróć uwagę, że projektant pokazuje teraz etykietę zajmującą niewielką ilość dostępnej wysokości. Jest teraz więcej miejsca na następny wiersz do zajmowania. Większość kontrolek definiuje jakiś rodzaj wartości wysokości i szerokości, które powinny zajmować, które najlepiej dla nich wyglądają. Na przykład kontrolka etykiety ma wartość wysokości, która gwarantuje, że można go odczytać.
Umieszczanie kontrolek
Porozmawiajmy o umieszczaniu kontrolek. Etykieta utworzona w powyższej sekcji została automatycznie umieszczona w wierszu 0 i kolumnie 0 siatki. Numerowanie wierszy i kolumn rozpoczyna się od 0 i zwiększa się o 1 dla każdego nowego wiersza lub kolumny. Kontrolka nie wie nic o siatce, a kontrolka nie definiuje żadnych właściwości do kontrolowania jej położenia w siatce. Kontrolka mogła zostać nawet umieszczona w innej kontrolce układu, która ma własny zestaw reguł definiujących sposób umieszczania kontrolek.
Jak poinformować kontrolkę o użyciu innego wiersza lub kolumny, gdy kontrolka nie zna siatki? Dołączone właściwości! Siatka korzysta z zaawansowanego systemu właściwości dostarczonego przez WPF. Siatka definiuje nowe właściwości, które kontrolki podrzędne mogą deklarować i używać. Właściwości nie istnieją w samej kontrolce, są one dołączone przez siatkę po dodaniu kontrolki do siatki.
Siatka definiuje dwie właściwości, aby określić położenie wiersza i kolumny kontrolki podrzędnej: Grid.Row
i Grid.Column
. Jeśli te właściwości zostaną pominięte w kontrolce, oznacza to, że mają wartości domyślne 0, dlatego kontrolka zostanie umieszczona w wierszu 0
i kolumnie 0
siatki. Spróbuj zmienić położenie kontrolki <Label>
, ustawiając Grid.Column
atrybut na 1
:
<Label Grid.Column="1">Names</Label>
Zwróć uwagę, że etykieta została przeniesiona do drugiej kolumny. Możesz użyć Grid.Row
właściwości i Grid.Column
dołączonych, aby umieścić następne kontrolki, które utworzymy. Na razie jednak przywróć etykietę do kolumny 0.
Tworzenie pola listy nazw
Teraz, gdy siatka ma prawidłowy rozmiar i utworzoną etykietę, dodaj kontrolkę pola listy w wierszu poniżej etykiety. Pole listy będzie znajdować się w wierszu 1
i kolumnie 0
. Nadamy również tej kontrolce lstNames
nazwę . Po nazwie kontrolki można odwoływać się do niej w kodzie. Nazwa jest przypisywana do kontrolki z atrybutem x:Name
.
<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>
Dodawanie pozostałych kontrolek
Ostatnie dwie kontrolki, które dodamy, to pole tekstowe i przycisk, którego użytkownik użyje do wprowadzenia nazwy w celu dodania do pola listy. Jednak zamiast próbować utworzyć więcej wierszy i kolumn dla siatki, umieścimy te kontrolki w kontrolce <StackPanel>
układu.
Panel stosu różni się od siatki w sposobie umieszczania kontrolek. Gdy informujesz siatkę, w której mają znajdować się kontrolki z dołączonymi właściwościami Grid.Row
i , Grid.Column
panel stosu działa automatycznie, umieszczając pierwszą kontrolkę, a następnie umieszczając następną kontrolkę po niej, kontynuując do momentu umieszczenia wszystkich kontrolek. Ta kontrolka "stosuje" każdą kontrolkę poniżej drugiej.
Utwórz kontrolkę <StackPanel>
po polu listy i umieść ją w kolumnie 1
wiersza 1
siatki . Dodaj inny atrybut o nazwie Margin
z wartością 5,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>
Atrybut Margin
był wcześniej używany w siatce, ale umieszczamy tylko w jednej wartości 10
. Teraz użyliśmy wartości 5,0,0,0
na panelu stosu. Margines jest typem Thickness
i może interpretować obie wartości. Grubość definiuje przestrzeń wokół każdej strony prostokątnej ramki, lewej, górnej, prawej, dolnej, odpowiednio. Jeśli wartość marginesu jest pojedynczą wartością, używa tej wartości dla wszystkich czterech stron.
Następnie utwórz kontrolkę <TextBox>
i <Button>
w pliku <StackPanel>
.
<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>
Układ okna został ukończony. Jednak nasza aplikacja nie ma w niej żadnej logiki, aby rzeczywiście była funkcjonalna. Następnie musimy podłączyć zdarzenia sterujące do kodu i pobrać aplikację, aby rzeczywiście coś zrobiła.
Dodawanie kodu dla zdarzenia Click
Utworzony <Button>
obiekt zawiera Click
zdarzenie, które jest zgłaszane, gdy użytkownik naciska przycisk. Możesz zasubskrybować to zdarzenie i dodać kod, aby dodać nazwę do pola listy. Podobnie jak w przypadku ustawiania właściwości kontrolki przez dodanie atrybutu XAML, możesz użyć atrybutu XAML do subskrybowania zdarzenia. Ustaw atrybut na Click
ButtonAddName_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>
Teraz musisz wygenerować kod programu obsługi. Kliknij prawym przyciskiem myszy ButtonAddName_Click
i wybierz polecenie Przejdź do definicji. Ta akcja generuje metodę w kodzie, która jest zgodna z wprowadzoną nazwą programu obsługi.
private void ButtonAddName_Click(object sender, RoutedEventArgs e)
{
}
Private Sub ButtonAddName_Click(sender As Object, e As RoutedEventArgs)
End Sub
Następnie dodaj następujący kod, aby wykonać trzy kroki:
- Upewnij się, że pole tekstowe zawiera nazwę.
- Sprawdź, czy nazwa wprowadzona w polu tekstowym jeszcze nie istnieje.
- Dodaj nazwę do pola listy.
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
Uruchom aplikację
Teraz, gdy zdarzenie zostało zakodowane, możesz uruchomić aplikację, naciskając F5 lub wybierając polecenie Debuguj>rozpocznij debugowanie z menu. Zostanie wyświetlone okno i możesz wprowadzić nazwę w polu tekstowym, a następnie dodać je, klikając przycisk.
Następne kroki
.NET Desktop feedback