Przejdź do treści
School IT / Przestrzeń do nauki

Projekt WPF i okno

Do tej pory programy działały w konsoli: wypisywały tekst i czekały na odpowiedź. Na egzaminie INF.04 część zadania to aplikacja z oknem. Zaczynamy od podstaw: tworzysz projekt, poznajesz jego pliki, ustawiasz okno i wyświetlasz w nim pierwszy napis — także z kodu C#.

C# XAML Window TextBlock x:Name InitializeComponent 90 min
CEL LEKCJI

Czego się dziś nauczysz

  • Wyjaśnisz, czym program sterowany zdarzeniami różni się od programu konsolowego.
  • Utworzysz projekt Aplikacja WPF dla .NET 10 i uruchomisz go.
  • Opiszesz rolę plików App.xaml, MainWindow.xaml i MainWindow.xaml.cs.
  • Wyjaśnisz, co robi InitializeComponent() i dlaczego kod zmieniający okno stoi po nim.
  • Ustawisz tytuł, rozmiar, tło i sposób zmiany rozmiaru okna.
  • Wyświetlisz napis TextBlock i zmienisz go z kodu przez nazwę z x:Name.
TEORIA

Konsola a okno — inny sposób myślenia

Program konsolowy sam prowadzi rozmowę: wypisuje pytanie, czeka na odpowiedź, liczy i kończy pracę. Program okienkowy wyświetla okno i czeka, aż użytkownik coś zrobi — kliknie, wpisze tekst — i dopiero wtedy reaguje. Takie działanie nazywamy programowaniem sterowanym zdarzeniami.

Aplikacja konsolowaAplikacja WPF
Kto decyduje o kolejnościprogram — instrukcja po instrukcjiużytkownik — działa w dowolnej kolejności
Wypisanie wynikuConsole.WriteLine()napis w oknie (TextBlock)
Wczytanie danychConsole.ReadLine()pole tekstowe (lekcja 07)
Koniec programupo ostatniej instrukcjigdy użytkownik zamknie okno

WPF (Windows Presentation Foundation) to część platformy .NET do aplikacji okienkowych. Program WPF ma dwie warstwy: wygląd opisany w języku XAML (czytaj: „zamel”) oraz działanie zapisane w C#.

A Windows Forms?

W Visual Studio zobaczysz też szablon Windows Forms — starszą technologię okienkową. W tym kursie używamy wyłącznie WPF: wygląd opisujemy w XAML, a okna dobrze dopasowują się do rozmiaru i skalowania ekranu.

TEORIA

Tworzenie projektu krok po kroku

Potrzebujesz Visual Studio 2026 z pakietem roboczym Programowanie aplikacji klasycznych .NET. Jeśli go brakuje, doinstalujesz go w programie Visual Studio Installer przyciskiem Modyfikuj.

KrokCo robiszNa co uważać
1Na ekranie startowym wybierz Utwórz nowy projekt.Z menu: Plik → Nowy → Projekt.
2Wyszukaj WPF i wybierz Aplikacja WPF z oznaczeniem C#.Nie wybieraj Aplikacja WPF (.NET Framework) — to stara platforma.
3Wpisz nazwę, np. Lekcja01, i wybierz folder.Bez spacji i polskich znaków — z nazwy powstaje przestrzeń nazw w kodzie.
4W polu Struktura wybierz .NET 10.0.Wszystkie przykłady kursu są dla .NET 10.
5Kliknij Utwórz i uruchom program klawiszem F5.Pojawi się puste okno „MainWindow”. Zamknij je, żeby wrócić do edycji.
Okno Visual StudioDo czego służy
Eksplorator rozwiązańLista plików projektu. Dwuklik otwiera plik.
Projektant (górna część pliku .xaml)Podgląd okna na żywo.
Edytor XAML (dolna część pliku .xaml)Tu piszesz wygląd okna. W kursie piszemy XAML ręcznie — tak jest dokładniej niż przeciąganiem z Przybornika.
WłaściwościWłaściwości zaznaczonego elementu.

F5 czy Ctrl + F5?

F5 uruchamia program z debugerem (można go zatrzymywać i podglądać zmienne), Ctrl + F5 — bez debugera, trochę szybciej. Część zmian w XAML widać od razu w działającym programie, ale zmiany w C# sprawdzaj po ponownym uruchomieniu.

TEORIA

Pliki nowego projektu

Lekcja01/
├── Lekcja01.csprojustawienia projektu: .NET 10, WPF
├── App.xamlaplikacja: które okno otworzyć na starcie
├── App.xaml.cskod aplikacji (na razie pusty)
├── AssemblyInfo.csinformacje techniczne — nie zmieniamy
├── MainWindow.xamlWYGLĄD głównego okna
└── MainWindow.xaml.csDZIAŁANIE głównego okna (code-behind)

Prawie całą pracę wykonujesz w dwóch ostatnich plikach. Tak wyglądają zaraz po utworzeniu projektu (szablon dodaje kilka dodatkowych linii, które na razie pomijamy):

MainWindow.xaml
<Window x:Class="Lekcja01.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="450" Width="800">
    <Grid>

    </Grid>
</Window>
MainWindow.xaml.cs
using System.Windows;

namespace Lekcja01;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
}
FragmentCo znaczy
x:Class="Lekcja01.MainWindow"Ten XAML opisuje klasę MainWindow z przestrzeni nazw Lekcja01. Musi się zgadzać z klasą w pliku .cs.
xmlns="…", xmlns:x="…"Przestrzenie nazw XAML — skąd pochodzą znaczniki. Nie zmieniamy ich.
<Grid> … </Grid>Pojemnik, który szablon wstawia do okna. Na razie traktuj go jako miejsce na jeden napis — jak dzielić go na wiersze i kolumny, nauczysz się w lekcji 09.
public partial class MainWindow : WindowKlasa okna. partial znaczy, że klasa jest podzielona na kilka plików — drugą część Visual Studio tworzy samo z XAML.
InitializeComponent();Wczytuje XAML i tworzy wszystko, co w nim opisano. Bez tej linii okno będzie puste.

Skąd program wie, które okno otworzyć?

Z pliku App.xaml: atrybut StartupUri="MainWindow.xaml" wskazuje okno startowe.

TEORIA

Właściwości okna

Wygląd i zachowanie okna ustawiasz atrybutami znacznika <Window>. Po wpisaniu spacji w znaczniku Visual Studio podpowie listę właściwości, a po =" — dozwolone wartości.

WłaściwośćPrzykładCo robi
Title"Biblioteka"Napis na pasku tytułu i na pasku zadań.
Width, Height480, 300Rozmiar okna przy otwarciu.
MinWidth, MinHeight380, 250Mniejszego okna użytkownik nie zrobi.
WindowStartupLocationCenterScreen, ManualGdzie okno się pojawi. Przy Manual położenie ustawiają Left i Top.
Left, Top20, 20Odległość okna od lewej i górnej krawędzi ekranu.
ResizeModeCanResize, CanMinimize, NoResizeCzy można zmieniać rozmiar. CanMinimize — tylko minimalizacja.
BackgroundAliceBlue, #FFEFEFEFTło okna — nazwa koloru albo zapis szesnastkowy (szczegóły w lekcji 06).
TopmostTrueOkno zawsze nad innymi oknami.

Każdą z tych właściwości możesz też ustawić w C#. W klasie okna piszesz samą nazwę, bez niczego przed kropką — bo chodzi o to okno:

MainWindow.xaml.cs
public MainWindow()
{
    InitializeComponent();

    Title = "Ustawione z kodu";   // to samo co Title="…" w XAML
    Width = 600;
    Topmost = true;
}
TEORIA

Pierwszy napis: TextBlock

TextBlock wyświetla tekst. Wstawiasz go do <Grid> z szablonu:

MainWindow.xaml
<Grid>
    <TextBlock x:Name="Powitanie"
               Text="Cześć!"
               FontSize="24" FontWeight="Bold" Foreground="DarkBlue"
               HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
WłaściwośćCo robi
TextWyświetlany tekst.
FontSize, FontWeightRozmiar czcionki (domyślnie 12) i grubość, np. Bold.
ForegroundKolor tekstu, np. DarkBlue.
HorizontalAlignment, VerticalAlignmentPołożenie napisu w oknie. Center — na środku. Bez nich napis stoi w lewym górnym rogu. Więcej w lekcji 05.
TextWrapping="Wrap"Długi tekst zawija się do nowej linii.
TextAlignment="Center"Wyśrodkowanie linii tekstu wewnątrz napisu.

x:Name — nazwa do użycia w kodzie

Atrybut x:Name="Powitanie" tworzy w klasie okna pole o tej nazwie. Dzięki temu w C# napiszesz Powitanie.Text = "…";. Nazwę nadajesz tylko elementom, które zmieniasz w kodzie. W kursie nazwy zaczynamy wielką literą i piszemy po polsku bez ogonków.

Najpierw InitializeComponent(), potem reszta

Napis Powitanie powstaje dopiero w InitializeComponent(). Kod, który go zmienia, musi stać pod tą linią — wcześniej pole Powitanie jest puste (null) i program zakończy się błędem przy starcie.

PRZYKŁAD

Okno biblioteki szkolnej

Okno ma stały rozmiar, jasnoniebieskie tło i napis powitalny na środku. Konstruktor dopisuje do tytułu dzisiejszą datę i zmienia napis — tak, jakby program sprawdzał godziny otwarcia.

Biblioteka szkolna — 08.10.2026–✕
Witaj w bibliotece szkolnej!
Dziś czynne do 15:30.

okno po uruchomieniu — tytuł i napis ustawił konstruktor

MainWindow.xaml — pełny plik
<Window x:Class="Lekcja01.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Biblioteka szkolna" Height="300" Width="480"
        MinHeight="250" MinWidth="380"
        WindowStartupLocation="CenterScreen"
        ResizeMode="CanMinimize"
        Background="AliceBlue">
    <Grid>
        <TextBlock x:Name="Powitanie"
                   Text="Witaj w bibliotece szkolnej!"
                   FontSize="24" FontWeight="Bold" Foreground="DarkBlue"
                   TextWrapping="Wrap" TextAlignment="Center"
                   HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</Window>
MainWindow.xaml.cs — pełny plik
using System.Windows;

namespace Lekcja01;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // Po InitializeComponent okno i napis już istnieją — można je zmieniać z kodu
        Title = $"Biblioteka szkolna — {DateTime.Now:dd.MM.yyyy}";
        Powitanie.Text = $"Witaj w bibliotece szkolnej!\nDziś czynne do 15:30.";
    }
}

Co dzieje się po kolei

  • App.xaml wskazuje MainWindow.xaml jako okno startowe, więc program tworzy obiekt MainWindow i wywołuje jego konstruktor.
  • InitializeComponent() czyta XAML: ustawia tytuł „Biblioteka szkolna”, rozmiar 480 × 300, tło i tworzy napis Powitanie.
  • Dopiero teraz wykonują się dwie linie pod spodem. Pierwsza nadpisuje tytuł z XAML — dlatego na pasku widać datę. {DateTime.Now:dd.MM.yyyy} wstawia dzisiejszą datę w formacie dzień.miesiąc.rok.
  • Druga linia zmienia tekst napisu. Znak \n to nowa linia — napis ma dwa wiersze, a TextAlignment="Center" wyśrodkowuje oba.
  • ResizeMode="CanMinimize" sprawia, że okna nie da się powiększyć ani przeciągnąć krawędzią — przycisk maksymalizacji zniknął.
  • Napis stoi na środku dzięki HorizontalAlignment i VerticalAlignment ustawionym na Center.

Sprawdź trzy rzeczy

  1. Przenieś linię Title = … nad InitializeComponent(). Na pasku znów zobaczysz „Biblioteka szkolna” — XAML wykonał się później i nadpisał tytuł z kodu.
  2. Przenieś nad InitializeComponent() linię Powitanie.Text = …. Program zakończy się przy starcie błędem NullReferenceException — napisu jeszcze nie było.
  3. Usuń HorizontalAlignment i VerticalAlignment. Napis przeskoczy do lewego górnego rogu.
ELEMENTY WBUDOWANE

Zestawienie elementów

ElementZnaczenieUwagi
Windowokno programuMoże zawierać tylko jeden element w środku.
Title, Width, Heighttytuł i rozmiar oknaW C# w klasie okna: Title = "…";
MinWidth, MinHeightminimalny rozmiarChroni napisy przed ucięciem.
WindowStartupLocationmiejsce otwarcia oknaCenterScreen albo Manual z Left/Top.
ResizeModezmiana rozmiaruCanResize (domyślnie), CanMinimize, NoResize.
Background, Topmosttło, okno zawsze na wierzchuW C#: Topmost = true;
TextBlocknapisTekst w Text. Dokładniej w lekcji 02.
x:Namenazwa elementu w kodzieTworzy pole w klasie okna.
InitializeComponent()tworzy okno z XAMLKod zmieniający elementy — zawsze pod nią.
DateTime.Nowbieżąca data i godzinaFormat w interpolacji: {DateTime.Now:dd.MM.yyyy}, {DateTime.Now:HH:mm}.
\nnowa linia w napisieDziała w Text ustawianym z C#.
CZĘSTE BŁĘDY

Zanim utkniesz

Zapis lub sytuacjaProblem
szablon Aplikacja WPF (.NET Framework)Projekt na starej platformie — inne pliki i ustawienia, część przykładów nie zadziała. Utwórz projekt jeszcze raz.
dwa TextBlock bezpośrednio w <Window>Błąd The property 'Content’ is set more than once. Okno ma jedno miejsce na zawartość — jak zmieścić więcej elementów, pokaże lekcja 03.
title="…" zamiast Title="…"XAML rozróżnia wielkość liter — właściwość title nie istnieje.
kod zmieniający napis nad InitializeComponent()NullReferenceException przy starcie — napis jeszcze nie istnieje.
usunięte InitializeComponent();Okno uruchamia się puste.
x:Class="Lekcja01.MainWindow", a w C# namespace Lekcja1;CS0103: The name 'InitializeComponent’ does not exist — XAML i C# opisują różne klasy. Kopiując kod z kursu, zmień Lekcja01 na nazwę swojego projektu w obu plikach.
Powitanie.text = "…";CS1061 — w C# też liczy się wielkość liter: właściwość to Text.
błąd MSB3027: The file is lockedProgram nadal działa (okno schowane za innymi). Zamknij go i zbuduj ponownie.
ZADANIA

Zadania

Każde zadanie wykonaj w nowym projekcie Aplikacja WPF. Wskazówkę otwórz dopiero wtedy, gdy utkniesz.

ZAD 1Kiosk informacyjny★☆☆

Szkoła stawia w holu ekran z informacją o dyżurach. Zbuduj okno o tytule „Informacja — sekretariat”, rozmiarze 600 × 260, otwierane na środku ekranu, bez możliwości zmiany rozmiaru (minimalizacja ma działać), z tłem Honeydew. Na środku okna wyświetl zawijany, wyśrodkowany napis rozmiaru 22: „Sekretariat czynny od poniedziałku do piątku w godzinach 7:30–15:30”. Zmień szerokość okna w XAML na 350 i sprawdź, czy napis nadal się mieści — w komentarzu w XAML zapisz, która właściwość napisu o tym decyduje.

Informacja — sekretariat–✕
Sekretariat czynny od poniedziałku do piątku w godzinach 7:30–15:30

oczekiwany wygląd (pomniejszony)

pokaż wskazówkę
  • Wszystko ustawisz w XAML — kod C# nie jest potrzebny.
  • Zawijanie i wyśrodkowanie linii tekstu to dwie różne właściwości napisu.
ZAD 2Dziennik z dzisiejszą datą★☆☆

Zbuduj okno „Dziennik”, w którym konstruktor ustawia tytuł w postaci „Dziennik — czwartek, 8 października 2026” (aktualny dzień tygodnia i data, po polsku), a napis na środku okna pokazuje bieżącą godzinę w formacie „Zalogowano o 12:05”. Uruchom program dwa razy w odstępie minuty i sprawdź, że godzina się zmienia. W komentarzu w kodzie napisz, dlaczego godzina w oknie nie zmienia się sama, gdy program jest otwarty.

pokaż wskazówkę
  • Dzień tygodnia i miesiąc słownie da format dddd, d MMMM yyyy, a godzinę — HH:mm.
  • Napis potrzebuje x:Name, a przypisania muszą stać pod InitializeComponent().
ZAD 3Odliczanie do wakacji★★☆

Okno „Ile jeszcze?” pokazuje dużym, pogrubionym napisem liczbę dni do najbliższych wakacji, np. „Do wakacji zostało 263 dni”. Datę początku wakacji zapisz w kodzie jako stałą (np. 27 czerwca 2027). Jeśli wakacje już trwają (liczba dni jest ujemna albo równa zero), napis ma brzmieć „Wakacje! Odpocznij od komputera.”. W tytule okna pokaż datę początku wakacji.

Ile jeszcze? (wakacje od 27.06.2027)–□✕
Do wakacji zostało 263 dni

przykładowy wynik

pokaż wskazówkę
  • Różnica dwóch dat (DateTime) daje przedział czasu, który ma właściwość Days. Porównuj daty bez godzin: DateTime.Today.
  • Wybór napisu to zwykłe if / else w konstruktorze.
ZAD 4Karteczka z przypomnieniem★★☆

Zbuduj małe okno „Pamiętaj!” o rozmiarze 260 × 140, które otwiera się w lewym górnym rogu ekranu (20 jednostek od krawędzi), jest zawsze nad innymi oknami, ma żółte tło i nie da się go zmniejszyć poniżej rozmiaru startowego. Napis: „Oddać projekt z programowania do piątku”. Sprawdź „zawsze na wierzchu”, klikając w inne okno. Następnie przenieś ustawienie Topmost z XAML do konstruktora i zapisz w komentarzu, czy coś się zmieniło.

pokaż wskazówkę
  • Żeby okno otworzyło się w podanym miejscu, WindowStartupLocation musi mieć wartość Manual.
  • Minimalny rozmiar ustawiają dwie właściwości z przedrostkiem Min.
ZAD 5Powitanie według pory dnia★★☆

Okno recepcji wita gościa w zależności od godziny uruchomienia: 5:00–11:59 „Dzień dobry!”, 12:00–17:59 „Miłego popołudnia!”, 18:00–21:59 „Dobry wieczór!”, w pozostałych godzinach „Dobranoc — recepcja nieczynna”. Tytuł okna zawiera godzinę, np. „Recepcja (12:05)”. Żeby przetestować wszystkie przypadki bez czekania, zapisz godzinę w zmiennej, którą na czas testów ustawisz ręcznie, a na koniec przywróć DateTime.Now.Hour. W komentarzu wypisz cztery godziny, którymi sprawdziłeś granice przedziałów.

pokaż wskazówkę
  • Godzinę jako liczbę daje DateTime.Now.Hour (0–23).
  • Najlepiej testować wartości na granicach: 5, 11, 12, 22 itd.
ZAD 6Znajdź pięć błędów★★★

Kolega przysłał projekt Kantor, który się nie kompiluje. Utwórz projekt o tej nazwie, przepisz kod i znajdź wszystkie błędy (jest ich pięć). Przy każdym poprawionym miejscu dopisz komentarz z opisem błędu. Program ma pokazywać na środku okna napis „Kurs euro: 4,30 zł”, a w tytule — godzinę uruchomienia.

MainWindow.xaml
<Window x:Class="Kantor.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        title="Kantor" Height="250" Width="350">
    <TextBlock x:Name="Kurs" Text="Kurs euro: 4,30 zł" FontSize="20"
               HorizontalAlignment="Center" VerticalAlignment="Center"/>
    <TextBlock Text="Zapraszamy"/>
</Window>
MainWindow.xaml.cs
using System.Windows;

namespace Kantor;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        kurs.Text = "Kurs euro: 4,30 zł";
        InitializeComponent()
        Title = $"Kantor ({DateTime.Now:HH:mm})";
    }
}
pokaż wskazówkę
  • Dwa błędy są w XAML: wielkość liter jednego atrybutu i liczba elementów bezpośrednio w oknie.
  • Trzy błędy są w C#: brakujący znak, nazwa niezgodna z x:Name i kolejność linii w konstruktorze.
  • Poprawiaj po jednym błędzie i czytaj listę błędów od góry — jeden błąd składni potrafi wywołać kilka komunikatów.
PODSUMOWANIE

Co trzeba zapamiętać

  • Program okienkowy jest sterowany zdarzeniami — czeka na działanie użytkownika.
  • Szablon: Aplikacja WPF (C#), struktura .NET 10.0 — nie wersja „.NET Framework”.
  • MainWindow.xaml — wygląd, MainWindow.xaml.cs — działanie. Razem tworzą jedną klasę (partial).
  • InitializeComponent() tworzy elementy z XAML; kod, który je zmienia, stoi pod tą linią.
  • Okno ma jedno miejsce na zawartość.
  • Title, Width, Height, MinWidth, WindowStartupLocation, ResizeMode, Background, Topmost — podstawowe właściwości okna, dostępne też z C#.
  • x:Name nadaje elementowi nazwę, przez którą zmienisz go w kodzie, np. Powitanie.Text = "…";.

Dokumentacja: Microsoft Learn — pierwsza aplikacja WPF, klasa Window.

Postęp zapisuje się w tej przeglądarce.