Lekcja 3. Pierwszy projekt .NET MAUI — struktura i podstawy XAML
PodstawowyPo co się tego uczymy?
Czas utworzyć pierwszą prawdziwą aplikację MAUI. Ta lekcja pokazuje, z jakich plików i folderów składa się świeży projekt, czym jest XAML i jak łączy się z kodem C# w tzw. code-behind — dokładnie tak samo jak w WPF, ale z innymi nazwami klas (ContentPage zamiast Window, AppShell zamiast samego MainWindow).
Teoria
Zanim zaczniesz — wymagany komponent Visual Studio. Szablon ".NET MAUI App" pojawia się na liście TYLKO, jeśli w Visual Studio Installer zaznaczony jest komponent (workload) ".NET Multi-platform App UI development" — jeśli go nie widzisz, doinstaluj go najpierw (Visual Studio Installer → Modyfikuj).
Wybór urządzenia docelowego. Obok zielonego przycisku Uruchom (▶) znajduje się rozwijana lista wyboru urządzenia — najprościej na start wybrać Windows Machine (uruchamia aplikację jako zwykłe okno na Twoim komputerze, bez potrzeby emulatora) — dopiero później, gdy chcesz przetestować zachowanie mobilne, wybierz emulator Androida z listy.
Tworzenie nowego projektu
W Visual Studio: Nowy projekt → wyszukaj ".NET MAUI App" → nadaj nazwę (np. PierwszaAplikacjaMaui) → Utwórz. Po chwili zobaczysz gotowy szablon startowy z licznikiem kliknięć.
Struktura projektu — co znaczy każdy plik/folder
| Plik / folder | Rola |
|---|---|
MauiProgram.cs |
Punkt startowy aplikacji — konfiguracja i uruchomienie (odpowiednik Program.cs). |
App.xaml / App.xaml.cs |
Zasoby globalne (style całej aplikacji) i logika startowa — która strona ma się pokazać jako pierwsza. |
AppShell.xaml / AppShell.xaml.cs |
Odpowiada za nawigację między stronami (tzw. Shell Navigation) — "mapa aplikacji" mówiąca, jakie strony istnieją i jak się między nimi poruszać. |
MainPage.xaml / MainPage.xaml.cs |
Interfejs (XAML) i logika (C#) głównej strony aplikacji — to Twój odpowiednik MainWindow z WPF. |
Resources/Fonts |
Własne czcionki dołączone do aplikacji. |
Resources/Images |
Grafiki i ikony aplikacji. |
Resources/Styles |
Pliki stylów XAML (odpowiednik arkuszy stylów). |
Resources/Raw |
Pliki dołączane w oryginalnej postaci (np. JSON). |
Platforms/ |
Kod specyficzny dla danego systemu (Android, iOS, Windows, MacCatalyst) — na start prawie nigdy tu nic nie zmieniamy. |
AppShell — "mapa" nawigacji aplikacji
AppShell działa jak spis treści aplikacji: mówi, jakie strony istnieją i jak można się między nimi poruszać, bez ręcznego pisania skomplikowanej logiki nawigacji. W tej lekcji mamy tylko jedną stronę, więc AppShell jest minimalny — do pełnej nawigacji między wieloma stronami wrócimy w osobnej, dedykowanej lekcji.
XAML — deklaratywny opis interfejsu
XAML (czytaj: "zamel") to język znaczników opisujący WYGLĄD aplikacji — dokładnie jak HTML opisuje strukturę strony internetowej, tylko dla aplikacji natywnych, nie stron WWW. Kluczowa zaleta: ten sam kod XAML działa na Androidzie, iOS i Windows (czasem wymagając drobnych dostosowań do konkretnej platformy — o tym w dalszej lekcji o dostosowaniu do platformy).
| HTML/CSS | XAML (.NET MAUI) |
|---|---|
| HTML opisuje strukturę strony | XAML opisuje strukturę aplikacji |
| CSS nadaje styl | Styl i układ są wbudowane w kontrolki albo definiowane w plikach Styles |
<button>Kliknij</button> |
<Button Text="Kliknij"/> |
Główną stroną aplikacji jest ContentPage — kontener będący odpowiednikiem Window z WPF. Wewnątrz niej umieszczamy layout (najczęściej VerticalStackLayout, o którym więcej w kolejnej lekcji), a wewnątrz layoutu — pojedyncze kontrolki.
Schemat
Struktura swiezego projektu .NET MAUI: PierwszaAplikacjaMaui/ ├── MauiProgram.cs <- punkt startowy, konfiguracja aplikacji ├── App.xaml(.cs) <- zasoby globalne, ktora strona startuje jako pierwsza ├── AppShell.xaml(.cs) <- "mapa" nawigacji miedzy stronami ├── MainPage.xaml(.cs) <- widok (XAML) i logika (C#) glownej strony ├── Resources/ │ ├── Fonts/ <- wlasne czcionki │ ├── Images/ <- grafiki i ikony │ ├── Styles/ <- style XAML │ └── Raw/ <- pliki dolaczane 1:1 (np. JSON) └── Platforms/ <- kod specyficzny dla Android/iOS/Windows/MacCatalyst
Przykład z życia
Podział na XAML (wygląd) i plik .xaml.cs (logika) działa dokładnie jak w WPF — jedna osoba w zespole może zajmować się samym wyglądem interfejsu, a druga logiką biznesową, pracując równolegle na tym samym ekranie bez wchodzenia sobie w drogę.
MainPage.xaml
<!-- MainPage.xaml -->
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="PierwszaAplikacjaMaui.MainPage">
<!-- VerticalStackLayout uklada elementy jeden pod drugim -->
<VerticalStackLayout Padding="30" Spacing="20">
<Label Text="Witaj w .NET MAUI!"
FontSize="26"
HorizontalOptions="Center" />
<Entry x:Name="PoleTekstowe"
Placeholder="Wpisz swoje imię"
FontSize="18" />
<Button Text="Kliknij mnie"
Clicked="OnButtonClicked" />
<Label x:Name="EtykietaWynik"
FontSize="22"
TextColor="DarkBlue"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentPage>
MainPage.xaml.cs
namespace PierwszaAplikacjaMaui;
// 'partial class' oznacza, ze klasa jest podzielona na dwie czesci:
// 1. czesc w pliku XAML (MainPage.xaml),
// 2. czesc w pliku C# (MainPage.xaml.cs).
// Obie razem tworza jedna klase MainPage.
public partial class MainPage : ContentPage
{
public MainPage()
{
// InitializeComponent() odczytuje XAML, tworzy wszystkie
// kontrolki (Label, Button, Entry) i laczy je z ta klasa.
InitializeComponent();
}
// Metoda obslugujaca klikniecie przycisku.
private void OnButtonClicked(object sender, EventArgs e)
{
string imie = PoleTekstowe.Text;
EtykietaWynik.Text = $"Witaj, {imie}!";
}
}
Komentarz i wyjaśnienie kodu
Plik MainPage.xaml definiuje wygląd: ContentPage jako główny kontener, wewnątrz VerticalStackLayout (pionowy układ elementów, więcej w kolejnej lekcji), a w nim etykieta powitalna, pole tekstowe (Entry — odpowiednik TextBox z WPF), przycisk i etykieta na wynik. Zwróć uwagę na x:Name — dokładnie jak w WPF, to identyfikator potrzebny, żeby odwołać się do kontrolki z poziomu C#.
Plik MainPage.xaml.cs to code-behind: konstruktor wywołuje InitializeComponent() (łączy XAML z klasą), a metoda OnButtonClicked odczytuje tekst z PoleTekstowe.Text i wypisuje spersonalizowane powitanie w EtykietaWynik.Text. Nazwa metody w atrybucie Clicked="OnButtonClicked" w XAML musi dokładnie odpowiadać nazwie metody w C# — identycznie jak w WPF.
Ćwiczenie samodzielne
Utwórz nowy projekt ".NET MAUI App", zastąp zawartość MainPage.xaml i MainPage.xaml.cs powyższym kodem (dostosuj x:Class i namespace do nazwy Twojego projektu). Uruchom aplikację na emulatorze skonfigurowanym w poprzedniej lekcji, wpisz imię i sprawdź, czy po kliknięciu przycisku pojawia się poprawne powitanie.
Zadania do pracy własnej
Zmień komunikat powitalny z „Witaj, [imię]!” na „Miło Cię poznać, [imię]!”.
Dodaj drugi przycisk „Wyczyść”, który czyści zarówno pole Entry, jak i etykietę z wynikiem.
Dodaj drugie pole Entry (na nazwisko) i zmień logikę tak, żeby po kliknięciu przycisku aplikacja wyświetlała pełne powitanie w formie „Witaj, [imię] [nazwisko]!”. Dodatkowo dodaj trzeci przycisk, który zmienia kolor tła strony (właściwość BackgroundColor strony ContentPage) na losowo wybrany z 3 kolorów.
Typowe błędy
Niezgodność x:Class z rzeczywistą nazwą klasy/projektu — jeśli skopiujesz XAML z innego projektu i nie zmienisz x:Class="StaraNazwa.MainPage", aplikacja się nie skompiluje.
Brak x:Name na kontrolce, do której chcesz się odwołać — bez tego atrybutu kompilator nie "widzi" kontrolki w pliku C#.
Mylenie ContentPage z Window — pojęciowo pełnią podobną rolę (główny kontener), ale to różne klasy z różnym zestawem właściwości — nie każda właściwość Window z WPF istnieje w ContentPage, i odwrotnie.
Zapomnienie o wybranym urządzeniu docelowym przed F5 — jak w poprzedniej lekcji, bez wybranego emulatora/urządzenia aplikacja się nie uruchomi.
Nawiązanie do egzaminu zawodowego
To realizacja INF.04.6.2 — "programuje aplikacje mobilne" w zakresie podstawowej struktury projektu i XAML. Rozumienie struktury projektu MAUI (MauiProgram.cs, App.xaml, AppShell, MainPage) jest fundamentem, na którym opiera się każda kolejna, bardziej rozbudowana aplikacja w tym dziale.