Dataniedziela, 9 sierpnia 2026 Czas06:58:14
← Aplikacje desktopowe (WPF)

Lekcja 5. Layouty i panele — Grid, StackPanel, WrapPanel, DockPanel

Średni

Po co się tego uczymy?

Samo dodanie kilku przycisków do okna to za mało — użytkownik musi się w interfejsie łatwo odnaleźć, a okno powinno wyglądać dobrze niezależnie od tego, jak je rozciągniemy. Do tego służą layouty (układy) — specjalne kontenery, które automatycznie rozmieszczają inne elementy, zamiast ręcznie ustawiać każdy piksel.

Teoria

Można powiedzieć, że layout to sposób ułożenia mebli w pokoju, a poszczególne kontrolki (przyciski, pola tekstowe) to te meble. Zamiast przesuwać każdy element ręcznie i liczyć piksele, mówimy panelowi "ułóż wszystko pionowo" albo "podziel okno na dwie kolumny", a on robi to automatycznie — również wtedy, gdy użytkownik zmieni rozmiar okna.

Najważniejsze panele układu w WPF:

  • Grid — dzieli okno na wiersze i kolumny (jak arkusz kalkulacyjny albo tabela HTML). To najczęściej używany panel, idealny do formularzy;
  • StackPanel — ustawia elementy jeden za drugim, w pionie (domyślnie) lub w poziomie (Orientation="Horizontal"). Świetny do prostych list i grup przycisków;
  • WrapPanel — ustawia elementy obok siebie i automatycznie "zawija" je w nowy rząd, gdy zabraknie miejsca — jak tekst, który się zawija na końcu linii;
  • DockPanel — przypina elementy do krawędzi okna: góry, dołu, lewej lub prawej strony. Klasyczne zastosowanie: pasek menu na górze, pasek statusu na dole, treść pośrodku;
  • Canvas — pozwala ustawić dokładną pozycję X/Y każdego elementu ręcznie. Rzadko używany do zwykłych formularzy (bo nie dostosowuje się do rozmiaru okna), ale przydatny do rysowania, gier czy diagramów;
  • GroupBox — nie jest typowym layoutem, tylko ramką z nagłówkiem, wewnątrz której umieszcza się inny panel — służy do wizualnego grupowania powiązanych pól formularza.

W praktyce panele często się zagnieżdża — np. DockPanel jako główny kontener okna (menu na górze, treść na środku), a wewnątrz treści Grid układający formularz w wiersze i kolumny.

Najważniejsze właściwości paneli

Właściwość Opis
Orientation Kierunek elementów w StackPanel: Horizontal lub Vertical.
Margin Odstęp zewnętrzny od innych elementów (góra, prawo, dół, lewo — np. Margin="0,5,0,0").
Padding Wewnętrzny odstęp od zawartości kontenera.
DockPanel.Dock Przypina element wewnątrz DockPanel do krawędzi: Top, Bottom, Left, Right.
HorizontalAlignment / VerticalAlignment Wyrównanie elementu: Left/Right/Center/Stretch (poziomo), Top/Bottom/Center/Stretch (pionowo).
Header Tytuł wyświetlany w nagłówku GroupBox lub MenuItem.
Grid.RowDefinitions / Grid.ColumnDefinitions Definicja podziału siatki Grid na wiersze/kolumny — szerokości Auto (dopasuj do treści), * (proporcjonalnie, cała reszta) albo konkretna liczba pikseli.
Grid.Row / Grid.Column Ustawiana na dziecku Grid — wskazuje, w której komórce siatki ma się znaleźć element.

Dla porównania: layouty w Windows Forms

Na egzaminie INF.04 może pojawić się pytanie dotyczące Windows Forms — starszej, lecz wciąż spotykanej technologii desktopowej w C#. W Windows Forms nie ma XAML — układ projektuje się wizualnie, przeciągając kontrolki myszą na formularz w Visual Studio. Rolę layoutów WPF pełnią tam inne kontenery:

WPF Odpowiednik w Windows Forms Działanie
StackPanel FlowLayoutPanel Ustawia elementy jeden po drugim, w rzędzie lub kolumnie.
Grid TableLayoutPanel Dzieli przestrzeń na wiersze i kolumny.
DockPanel właściwość Dock kontrolki + MenuStrip/ToolStrip Przypina elementy do krawędzi formularza.
GroupBox GroupBox Ramka z tytułem — ta sama nazwa w obu technologiach.
SplitContainer Dzieli okno na dwie części z ruchomym uchwytem (w WPF podobny efekt daje GridSplitter).

Kluczowa różnica: WPF automatycznie dopasowuje układ do rozmiaru okna dzięki deklaratywnemu, elastycznemu XAML, natomiast Windows Forms opiera się bardziej na współrzędnych i właściwości Anchor (przyklejenie krawędzi kontrolki do krawędzi formularza przy zmianie rozmiaru) — układ jest z natury bardziej statyczny i wymaga więcej ręcznej pracy przy dostosowywaniu do różnych rozdzielczości.

Schemat

Najwazniejsze panele ukladu w WPF:

Grid (wiersze x kolumny)      StackPanel (jeden rzad/kolumna)
┌─────────┬─────────┐         ┌─────────────────┐
│  [0,0]  │  [0,1]  │         │     Element 1    │
├─────────┼─────────┤         ├─────────────────┤
│  [1,0]  │  [1,1]  │         │     Element 2    │
└─────────┴─────────┘         ├─────────────────┤
                                │     Element 3    │
                                └─────────────────┘

WrapPanel (zawija w nowy rzad)    DockPanel (przypina do krawedzi)
┌───┬───┬───┐                    ┌───────Top────────┐
│ A │ B │ C │                    │Left│ srodek │Right│
├───┼───┘                        │    │         │     │
│ D │  <- zawiniete               ├────┴─────────┴─────┤
└───┘                             │       Bottom        │
                                   └─────────────────────┘

Przykład z życia

Otwórz dowolny program biurowy — pasek menu zawsze jest przypięty do góry okna (to DockPanel), przyciski w oknie dialogowym "Zapisz jako" są ułożone w rzędzie na dole (to StackPanel poziomy), a formularz z danymi osobowymi ma etykiety i pola ułożone w równe kolumny (to Grid) — nawet jeśli okno zostanie rozciągnięte na cały ekran, układ pozostaje czytelny, bo panele same przeliczają rozmieszczenie.

Kod (XAML)

<Window x:Class="UkladyApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Formularz uzytkownika" Height="300" Width="400">
    <DockPanel>
        <!-- Pasek menu przypiety do gory -->
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_Plik">
                <MenuItem Header="Nowy" />
                <MenuItem Header="Zapisz" />
                <Separator />
                <MenuItem Header="Zamknij" />
            </MenuItem>
        </Menu>

        <!-- Glowna sekcja z formularzem w Grid wewnatrz GroupBox -->
        <GroupBox Header="Dane uzytkownika" Margin="10">
            <Grid Margin="10">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>

                <Label Content="Imie:" Grid.Row="0" Grid.Column="0" />
                <TextBox Grid.Row="0" Grid.Column="1" Margin="5" />

                <Label Content="Nazwisko:" Grid.Row="1" Grid.Column="0" />
                <TextBox Grid.Row="1" Grid.Column="1" Margin="5" />
            </Grid>
        </GroupBox>
    </DockPanel>
</Window>

Komentarz i wyjaśnienie kodu

Główny kontener to DockPanelMenu ma ustawione DockPanel.Dock="Top", więc zawsze zostanie przypięty do góry okna, niezależnie od jego rozmiaru. Reszta przestrzeni (domyślnie ostatni element w DockPanel wypełnia pozostałe miejsce) należy do GroupBox z formularzem.

Wewnątrz GroupBox mamy Grid z dwoma zdefiniowanymi wierszami (RowDefinitions) i dwiema kolumnami (ColumnDefinitions) — pierwsza kolumna ma szerokość Auto (dopasowuje się do treści etykiety), druga * (zajmuje całą resztę dostępnego miejsca). Każda kontrolka wskazuje, w którym wierszu/kolumnie ma się znaleźć przez Grid.Row i Grid.Column — to jak podanie współrzędnych komórki w tabeli.

Ćwiczenie samodzielne

Utwórz nowy projekt WPF, wklej powyższy XAML i uruchom aplikację. Zmień szerokość okna (przeciągając krawędź) i zaobserwuj, jak menu zawsze zostaje na górze, a pola formularza dopasowują szerokość do dostępnego miejsca.

Zadania do pracy własnej

  1. Zbuduj okno z StackPanel (poziomym, Orientation="Horizontal") zawierającym trzy przyciski obok siebie: "Dodaj", "Edytuj", "Usuń".

  2. Rozbuduj formularz z lekcji o trzecie pole (Email) i dodaj na dole (przypięty przez DockPanel.Dock="Bottom") pasek z przyciskami "Zapisz" i "Anuluj" ułożonymi poziomo.

  3. Zaprojektuj okno symulujące prosty edytor zdjęć: pasek menu na górze (DockPanel.Dock="Top"), pasek narzędzi z ikonami po lewej (DockPanel.Dock="Left", WrapPanel pionowy), pasek statusu na dole, a na środku duży obszar roboczy (może być zwykły Border z szarym tłem, symbolizujący miejsce na obraz).

Typowe błędy

Używanie Canvas jako głównego układu okna — pozycje X/Y ustawione ręcznie NIE dostosowują się do zmiany rozmiaru okna, przez co interfejs "rozjeżdża się" przy innej rozdzielczości ekranu. Canvas ma sens tylko do specyficznych zastosowań (rysowanie, gry).

Zapominanie o RowDefinitions/ColumnDefinitions w Grid — bez jawnego zdefiniowania wierszy/kolumn, Grid ma domyślnie tylko jeden wiersz i jedną kolumnę, więc wszystkie elementy nakładają się na siebie w tym samym miejscu.

Mylenie kolejności elementów w DockPanel — elementy dokują się w kolejności, w jakiej występują w XAML; ostatni element (bez ustawionego Dock) domyślnie wypełnia całą pozostałą przestrzeń.

Nawiązanie do egzaminu zawodowego

To rozwinięcie efektu INF.04.5.3 w części dotyczącej projektowania interfejsu okna. Dobrze dobrany layout to podstawa czytelnej aplikacji — w kolejnej lekcji dodamy do tych paneli prawdziwe, interaktywne kontrolki i nauczymy się obsługiwać zdarzenia.