Dataniedziela, 9 sierpnia 2026 Czas07:52:44
← Aplikacje mobilne (.NET MAUI)

Lekcja 11. Nawigacja I — NavigationPage i nawigacja modalna

Trudny / egzaminacyjny

Po co się tego uczymy?

Rzadko aplikacja mobilna ma tylko jeden ekran — zwykle są ekrany logowania, listy, szczegółów, ustawień. Nawigacja to mechanizm przechodzenia między nimi. Ta lekcja pokazuje dwa klasyczne sposoby: NavigationPage (stos stron, "przejdź dalej/wróć") i nawigację modalną (pełnoekranowe okno na wierzchu). Trzeci, nowoczesny sposób — Shell — poznasz w kolejnej lekcji.

Teoria

NavigationPage — stos stron

Działa jak stos kartek: PushAsync() dokłada nową kartkę (nową stronę) na wierzch, PopAsync() zdejmuje ją, wracając do poprzedniej. To najprostszy sposób realizacji klasycznego "przejdź dalej / wróć", np. lista uczniów → szczegóły ucznia.

Metoda Działanie
await Navigation.PushAsync(new DrugaStrona()) Przejście do nowej strony (dokłada ją na stos).
await Navigation.PopAsync() Powrót do poprzedniej strony (zdejmuje bieżącą ze stosu).

Żeby NavigationPage działał, trzeba go ustawić jako główną stronę aplikacji w App.xaml.cs: MainPage = new NavigationPage(new MainPage());

Nawigacja modalna — okno na wierzchu

To jak otwarcie pełnoekranowego okna dialogowego — dopóki go nie zamkniesz, nie wrócisz do poprzedniej strony. Typowe zastosowanie: formularze, logowanie, potwierdzenia, okna wyboru.

Metoda Działanie
await Navigation.PushModalAsync(new Strona()) Otwiera stronę jako modalne okno "na wierzchu".
await Navigation.PopModalAsync() Zamyka modalne okno, wracając do strony pod spodem.

Przekazywanie danych między stronami — dwa sposoby

Przez konstruktor — dane przekazujesz w momencie TWORZENIA strony: await Navigation.PushAsync(new SecondPage(imie));, a druga strona odbiera je w swoim konstruktorze.

Przez właściwość — najpierw tworzysz stronę, POTEM ustawiasz jej właściwość publiczną, a odczytujesz ją w metodzie OnAppearing() (poznanej w pierwszej lekcji tego działu — uruchamia się dokładnie wtedy, gdy strona staje się widoczna):

var third = new ThirdPage();
third.Imie = _imie;  // przekazanie danych przez wlasciwosc, PRZED PushAsync
await Navigation.PushAsync(third);

Oba sposoby są proste i w pełni wystarczające na egzaminie INF.04.

Schemat

Trzy sposoby nawigacji (ten i nastepny wykladany w tej lekcji: dwa pierwsze):

NavigationPage (stos kartek):
  MainPage --PushAsync--> SecondPage --PushAsync--> ThirdPage
  MainPage <--PopAsync--- SecondPage <--PopAsync--- ThirdPage

Modal (okno na wierzchu, blokuje powrot dopoki nie zamkniesz):
  MainPage --PushModalAsync--> [OKNO MODALNE] --PopModalAsync--> MainPage

Przykład z życia

Formularz "Dodaj nowy kontakt" otwierający się jako pełnoekranowe okno NA WIERZCHU listy kontaktów, które trzeba świadomie zamknąć (przyciskiem "Zapisz" albo "Anuluj") — to klasyczny wzorzec nawigacji modalnej. Z kolei przechodzenie z listy produktów do szczegółów produktu, a potem powrót do listy przez strzałkę "wstecz" — to typowy NavigationPage.

MainPage.xaml

<!-- MainPage.xaml -->
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="NawigacjaApp.MainPage">

    <VerticalStackLayout Padding="20" Spacing="12">
        <Entry x:Name="PoleImie" Placeholder="Podaj imię" />
        <Button Text="Przejdź dalej" Clicked="OnGoClicked" />
    </VerticalStackLayout>
</ContentPage>

MainPage.xaml.cs + SecondPage.xaml.cs

// MainPage.xaml.cs
namespace NawigacjaApp;

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }

    private async void OnGoClicked(object sender, EventArgs e)
    {
        string imie = PoleImie.Text ?? "";
        // Przekazanie danych PRZEZ KONSTRUKTOR drugiej strony
        await Navigation.PushAsync(new SecondPage(imie));
    }
}

// SecondPage.xaml.cs
namespace NawigacjaApp;

public partial class SecondPage : ContentPage
{
    public SecondPage(string imie)
    {
        InitializeComponent();
        LabelImie.Text = $"Witaj, {imie}!";
    }

    private async void OnBackClicked(object sender, EventArgs e)
    {
        // Powrot do poprzedniej strony (zdejmuje SecondPage ze stosu)
        await Navigation.PopAsync();
    }
}

Komentarz i wyjaśnienie kodu

Na MainPage użytkownik wpisuje imię, a kliknięcie przycisku wywołuje Navigation.PushAsync(new SecondPage(imie)) — tworzy nową instancję SecondPage, przekazując wpisane imię PROSTO do jej konstruktora, i dokłada tę stronę na "stos" nawigacji.

SecondPage odbiera imię jako parametr konstruktora i od razu wypisuje powitanie w LabelImie. Przycisk "Wróć" wywołuje Navigation.PopAsync(), który zdejmuje SecondPage ze stosu, automatycznie wracając do MainPage — nie trzeba samodzielnie "pamiętać", skąd użytkownik przyszedł, MAUI robi to za nas.

Zwróć uwagę: żeby Navigation.PushAsync/PopAsync w ogóle działały, aplikacja musi być uruchomiona wewnątrz NavigationPage — ustawionego w App.xaml.cs jako MainPage = new NavigationPage(new MainPage());.

Ćwiczenie samodzielne

Utwórz projekt z dwiema stronami (MainPage, SecondPage) i powyższym kodem, pamiętając o ustawieniu NavigationPage w App.xaml.cs. Sprawdź na emulatorze: czy natywny przycisk "wstecz" (albo strzałka w górnym pasku) też poprawnie wraca do MainPage — to jedna z korzyści korzystania z NavigationPage zamiast ręcznego zarządzania stronami.

Zadania do pracy własnej

  1. Dodaj trzecią stronę ThirdPage i przycisk na SecondPage, który otwiera ją MODALNIE (PushModalAsync) zamiast przez zwykły PushAsync. Zaobserwuj różnicę: czy pojawia się przycisk 'wstecz'?

  2. Przekaż z SecondPage do ThirdPage dane PRZEZ WŁAŚCIWOŚĆ (nie przez konstruktor) — utwórz ThirdPage z publiczną właściwością Imie, ustaw ją PRZED wywołaniem PushAsync, a odczytaj w metodzie OnAppearing().

  3. Zbuduj aplikację 'Lista zadań' z trzema stronami: ListaPage (przycisk 'Dodaj zadanie'), DodajZadaniePage (otwierana MODALNIE, z Entry na treść zadania i przyciskami 'Zapisz'/'Anuluj' — Zapisz zamyka modal przez PopModalAsync i przekazuje wpisany tekst z powrotem przez właściwość publiczną odczytaną po PopModalAsync), i SzczegolyZadaniaPage (otwierana zwykłym PushAsync z listy, pokazuje treść zadania i przycisk 'Wróć').

Typowe błędy

Brak NavigationPage w App.xaml.cs — bez tego wywołanie Navigation.PushAsync rzuci wyjątek, bo strona nie ma dostępu do stosu nawigacji.

Mylenie PushAsync z PushModalAsync — obie "otwierają nową stronę", ale modal blokuje dostęp do przycisku "wstecz" i wymaga jawnego zamknięcia przez PopModalAsync — dobór złej metody psuje oczekiwane zachowanie ekranu.

Ustawianie właściwości PO wywołaniu PushAsync zamiast przed — jeśli ustawisz właściwość strony już PO jej wyświetleniu, `OnAppearing()` zdąży się wykonać z pustą wartością.

Zapominanie o await przed Push/PopAsync — te metody są asynchroniczne; pominięcie await może prowadzić do nieprzewidywalnego zachowania animacji przejścia.

Nawiązanie do egzaminu zawodowego

To realizacja INF.04.6.2 w zakresie nawigacji — kluczowego elementu każdej wieloekranowej aplikacji mobilnej. Umiejętność poprawnego przekazania danych między stronami (przez konstruktor lub właściwość) jest częstym elementem zadań egzaminacyjnych.