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

Składnia XAML i TextBlock

XAML wygląda jak HTML, ale rządzi się ściślejszymi zasadami: rozróżnia wielkość liter, każdy znacznik musi być zamknięty, a każdy znacznik tworzy prawdziwy obiekt C#. Poznasz te zasady na przykładzie napisu TextBlock, nauczysz się formatować fragmenty tekstu i zapisywać właściwości, które nie mieszczą się w zwykłym atrybucie.

C# XAML TextBlock Run LineBreak LinearGradientBrush 90 min
CEL LEKCJI

Czego się dziś nauczysz

  • Wyjaśnisz, że znacznik XAML tworzy obiekt, a atrybut ustawia jego właściwość, i zapiszesz ten sam napis w XAML i w C#.
  • Zastosujesz zasady zapisu XAML: wielkość liter, zamykanie znaczników, cudzysłowy.
  • Zapiszesz poprawnie liczby, kolory i wartości wyliczeniowe, także ułamki i znaki specjalne.
  • Sformatujesz napis właściwościami czcionki, koloru, zawijania i wyrównania.
  • Złożysz jeden napis z fragmentów o różnym wyglądzie (Run, Bold, Italic, LineBreak).
  • Zapiszesz właściwość jako element, gdy wartość jest obiektem — na przykładzie tła z gradientem.
TEORIA

Znacznik to obiekt, atrybut to właściwość

XAML (eXtensible Application Markup Language) to krótszy zapis tworzenia obiektów. Każdy znacznik tworzy obiekt klasy o tej samej nazwie, każdy atrybut ustawia jedną właściwość. Te dwa zapisy robią dokładnie to samo:

XAML
<TextBlock Text="Witaj" FontSize="20" Foreground="DarkBlue"/>
C# — ten sam napis
TextBlock napis = new TextBlock();    // <TextBlock
napis.Text = "Witaj";                 //   Text="Witaj"
napis.FontSize = 20;                  //   FontSize="20"
napis.Foreground = Brushes.DarkBlue;  //   Foreground="DarkBlue"/>
Content = napis;                      // włożenie napisu do okna

Zasada „znacznik = new, atrybut = przypisanie” tłumaczy każdy błąd w XAML: jeśli klasa nie ma danej właściwości w C#, to atrybut o tej nazwie też nie zadziała. W kursie wygląd okna opisujemy w XAML, bo od razu widać w nim strukturę. Kolory w C# (Brushes) dokładnie poznasz w lekcji 06 — tu wystarczy, że widzisz odpowiednik.

TEORIA

Zasady zapisu

ZasadaPrzykład
wielkość liter ma znaczenie<TextBlock> ✓   <textblock> ✗   FontSize ✓   fontsize ✗
każdy znacznik jest zamknięty<TextBlock> … </TextBlock> albo samozamykający <TextBlock … />
znaczniki zamykamy w odwrotnej kolejnościjak nawiasy: otwarty później — zamknięty wcześniej
wartość atrybutu zawsze w cudzysłowieFontSize="20" ✓   FontSize=20 ✗
atrybut tylko raz w znaczniku<TextBlock Text="A" Text="B"/> ✗
kolejność atrybutów nie ma znaczeniaText="A" FontSize="20" = FontSize="20" Text="A"
komentarz<!-- tekst --> — nie może stać w środku znacznika, między atrybutami
TEORIA

Jak XAML czyta wartości

Każdy atrybut to tekst, ale właściwości mają różne typy. XAML zamienia tekst na właściwy typ:

Typ właściwościZapis w XAMLUwagi
liczbaFontSize="20", Opacity="0.5"ułamki zawsze z kropką, niezależnie od ustawień Windows; Opacity to nieprzezroczystość od 0 (niewidoczny) do 1 (pełny)
logicznaTopmost="True"True / False
kolorForeground="DarkRed", "#8B0000"nazwa albo zapis szesnastkowy
wyliczenieFontWeight="Bold", TextAlignment="Center"jedna z nazw podpowiadanych przez edytor
tekstText="Ala ma kota"znaki specjalne — patrz niżej

Znaki <, >, & i " mają w XAML znaczenie specjalne. W tekście zapisz je jako encje: &lt;, &gt;, &amp;, &quot;. Przykład: Text="Ben &amp; Jerry" wyświetli „Ben & Jerry”. Nową linię w atrybucie zapiszesz encją &#10;.

TEORIA

Właściwości TextBlock

WłaściwośćPrzykładowe wartościCo robi
FontSize12 (domyślnie), 20rozmiar czcionki
FontWeightNormal, SemiBold, Boldgrubość
FontStyleNormal, Italickursywa
FontFamilySegoe UI, Consolas, Georgiakrój pisma
Foreground, BackgroundDarkRed, LightYellowkolor tekstu i tła napisu
TextWrappingNoWrap (domyślnie), Wrapzawijanie długiego tekstu
TextAlignmentLeft, Center, Right, Justifywyrównanie linii tekstu
TextDecorationsUnderline, Strikethroughpodkreślenie, przekreślenie
LineHeight28odstęp między liniami

Czcionka w całym oknie

FontSize i FontFamily możesz też ustawić na Window — wtedy obowiązują dla wszystkich napisów, które nie mają własnej wartości. To tzw. dziedziczenie wartości; dokładniej w lekcji 05.

TEORIA

Fragmenty tekstu w jednym napisie

Atrybut Text daje jeden wygląd dla całego napisu. Gdy część tekstu ma być pogrubiona albo w innym kolorze, zamiast atrybutu wpisz zawartość między znacznikami <TextBlock> i </TextBlock>:

MainWindow.xaml
<TextBlock FontSize="16" TextWrapping="Wrap">
    Sprawdzian z <Bold>matematyki</Bold> odbędzie się
    <Run Text="w piątek" Foreground="Red" FontWeight="Bold"/>.
    <LineBreak/>
    <Italic>Przynieś kalkulator.</Italic>
</TextBlock>
Ogłoszenie–□✕
Sprawdzian z matematyki odbędzie się w piątek.
Przynieś kalkulator.

jeden TextBlock, cztery różne fragmenty

ElementCo robi
<Run Text="…"/>Fragment tekstu z własnymi właściwościami: Foreground, FontSize, FontWeight… Może mieć x:Name i zmieniać się z kodu.
<Bold>…</Bold>Pogrubiony fragment.
<Italic>…</Italic>Kursywa.
<Underline>…</Underline>Podkreślenie.
<LineBreak/>Przejście do nowej linii.

Enter w XAML to spacja

Przejście do nowej linii w kodzie XAML między fragmentami zamienia się w jedną spację — nie w nową linię na ekranie. Nową linię robi tylko <LineBreak/>. Dlatego <Run Text="Stan na:"/> zapisany w jednej linii, a <Run x:Name="Data"/> w następnej dadzą razem „Stan na: 08.10.2026” — ze spacją, której nikt nie wpisał.

TEORIA

Właściwość zapisana jako element

Atrybut przyjmuje tylko tekst. Gdy wartość jest złożonym obiektem — np. tłem, którego kolor płynnie się zmienia — zapisujesz właściwość jako element w postaci <Klasa.Właściwość>:

MainWindow.xaml
<Window …>
    <Window.Background>
        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
            <GradientStop Color="LightYellow" Offset="0"/>
            <GradientStop Color="Orange" Offset="1"/>
        </LinearGradientBrush>
    </Window.Background>

    <TextBlock Text="Ogłoszenie"/>
</Window>

Kropka w nazwie znacznika oznacza: „to nie jest nowy obiekt, tylko właściwość Background obiektu Window”. LinearGradientBrush to tło z przejściem kolorów: StartPoint i EndPoint wyznaczają kierunek (0,0 — lewy górny róg, 0,1 — lewy dolny, czyli z góry na dół), a każdy GradientStop to kolor w miejscu Offset od 0 do 1.

Zapis jako atrybut Background="Orange" i jako element to dwa sposoby ustawienia tej samej właściwości. Nie wolno użyć obu naraz.

Okno ma jedną zawartość

<Window.Background> nie jest zawartością okna, tylko jego właściwością — dlatego obok niego może stać jeszcze jeden element (tu: TextBlock). Dwóch napisów bezpośrednio w oknie nadal nie zmieścisz.

PRZYKŁAD

Ogłoszenie kółka programistycznego

Całe ogłoszenie to jeden TextBlock złożony z fragmentów o różnym wyglądzie. Tło okna to gradient od jasnożółtego do pomarańczowego, a data „stan na” ustawia się sama przy uruchomieniu.

Ogłoszenie–□✕
KÓŁKO PROGRAMISTYCZNE
Nauczymy Cię pisać aplikacje okienkowe

Każdy czwartek, sala 21, godz. 14:30
Zapisy u wychowawcy

Stan na: 08.10.2026

okno po uruchomieniu

MainWindow.xaml — pełny plik
<Window x:Class="Lekcja02.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Ogłoszenie" Height="360" Width="460"
        WindowStartupLocation="CenterScreen">

    <!-- Właściwość zapisana jako element: tło z gradientem -->
    <Window.Background>
        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
            <GradientStop Color="LightYellow" Offset="0"/>
            <GradientStop Color="Orange" Offset="1"/>
        </LinearGradientBrush>
    </Window.Background>

    <!-- Jeden TextBlock, a w nim fragmenty o różnym wyglądzie -->
    <TextBlock TextAlignment="Center" TextWrapping="Wrap"
               HorizontalAlignment="Center" VerticalAlignment="Center"
               FontSize="16">
        <Run Text="KÓŁKO PROGRAMISTYCZNE" FontSize="26" FontWeight="Bold" Foreground="DarkRed"/>
        <LineBreak/>
        <Italic>Nauczymy Cię pisać aplikacje okienkowe</Italic>
        <LineBreak/>
        <LineBreak/>
        <Run Text="Każdy czwartek, sala 21, godz. 14:30"/>
        <LineBreak/>
        <Bold>Zapisy u wychowawcy</Bold>
        <LineBreak/>
        <LineBreak/>
        <Run Text="Stan na:" Foreground="Gray"/>
        <Run x:Name="Data" Foreground="Gray"/>
    </TextBlock>
</Window>
MainWindow.xaml.cs — pełny plik
using System.Windows;

namespace Lekcja02;

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

        // Run też może mieć nazwę i zmieniać się z kodu
        Data.Text = DateTime.Now.ToString("dd.MM.yyyy");
    }
}

Co dzieje się po kolei

  • <Window.Background> ustawia tło okna. Gradient biegnie z góry (0,0) na dół (0,1): na górze jasnożółty, na dole pomarańczowy.
  • Jedyną zawartością okna jest TextBlock. Jego wspólne ustawienia — wyśrodkowanie, zawijanie, rozmiar 16 — dotyczą wszystkich fragmentów, chyba że fragment ma własne.
  • Pierwszy Run ma własny FontSize="26", kolor i pogrubienie — dlatego tytuł jest większy od reszty.
  • Każdy <LineBreak/> to nowa linia. Dwa pod rząd dają pustą linię odstępu.
  • <Italic> i <Bold> zawierają zwykły tekst między znacznikami — nie potrzebują Run.
  • Ostatni Run ma nazwę Data. Konstruktor wpisuje do niego dzisiejszą datę metodą ToString("dd.MM.yyyy").
  • Między „Stan na:” a datą widać spację, choć nie ma jej w żadnym Text — to przejście do nowej linii w kodzie XAML między dwoma Run.

Sprawdź trzy rzeczy

  1. Zmień EndPoint="0,1" na EndPoint="1,0". Gradient pobiegnie od lewej do prawej.
  2. Dopisz do znacznika <TextBlock> atrybut Text="Test". Dostaniesz błąd — tekst ustawiony jest teraz dwa razy: atrybutem i zawartością.
  3. Zapisz oba ostatnie Run w jednej linii, bez spacji między nimi: …Foreground="Gray"/><Run x:Name=…. Spacja przed datą zniknie.
ELEMENTY WBUDOWANE

Zestawienie elementów

ElementZnaczenieUwagi
TextBlocknapisTekst w Text albo jako zawartość z fragmentami.
FontSize, FontWeight, FontStyle, FontFamilyczcionkaMogą być ustawione też na fragmencie lub na oknie.
TextWrapping, TextAlignmentzawijanie i wyrównanie liniiDługi tekst bez Wrap wychodzi poza okno.
TextDecorationspodkreślenie, przekreślenieUnderline, Strikethrough.
Runfragment tekstuMa własne właściwości i może mieć x:Name.
Bold, Italic, Underlinefragment z formatowaniemTekst wpisujesz między znacznikami.
LineBreaknowa liniaEnter w kodzie XAML to tylko spacja.
<Window.Background>właściwość jako elementDla wartości, które nie mieszczą się w atrybucie.
LinearGradientBrush, GradientStoptło z przejściem kolorówKierunek: StartPoint/EndPoint; kolory: Color i Offset 0–1.
&lt;, &amp;, &#10;encjeZnaki specjalne i nowa linia w atrybucie.
ToString("dd.MM.yyyy")data jako tekstFormat daty dla DateTime.
CZĘSTE BŁĘDY

Zanim utkniesz

ZapisProblem
<TextBlock Text="A">B</TextBlock>Tekst ustawiony dwa razy — atrybutem i zawartością. Wybierz jeden sposób.
Opacity="0,5"W XAML ułamki zawsze z kropką: 0.5.
FontSize=20Brak cudzysłowu — atrybut nie zostanie przyjęty.
Text="x < 10"Znak < w tekście trzeba zapisać jako &lt;.
<Bold> otwarty, a zamknięty </TextBlock>Znaczniki zamykamy w odwrotnej kolejności niż otwieramy.
Background="Orange" i <Window.Background> narazTa sama właściwość ustawiona dwa razy.
<TextBlock.Background> wewnątrz <Window>Przedrostek musi być nazwą klasy elementu, w którym stoisz: <Window.Background>.
Enter w XAML, żeby przejść do nowej liniiNa ekranie pojawi się tylko spacja. Użyj <LineBreak/>.
Foreground="Ciemnoczerwony"Nazwy kolorów są angielskie. Gdy nie znasz nazwy, wpisz # i kod szesnastkowy (lekcja 06).
ZADANIA

Zadania

Każde zadanie wykonaj w nowym projekcie Aplikacja WPF. Okno ma jedno miejsce na zawartość — w tej lekcji wszystko mieści się w jednym TextBlock. Wskazówkę otwórz dopiero wtedy, gdy utkniesz.

ZAD 1Z C# do XAML★☆☆

Zapisz w XAML napis, który ten kod tworzy w C#. Uruchom program i porównaj wygląd z opisem w komentarzach. W komentarzu XAML przy każdym atrybucie napisz, którą linię z C# zastępuje.

C# do przepisania
TextBlock baner = new TextBlock();
baner.Text = "Promocja: drugi zeszyt gratis!";
baner.FontSize = 28;
baner.FontWeight = FontWeights.Bold;
baner.FontStyle = FontStyles.Italic;
baner.Foreground = Brushes.Crimson;
baner.TextWrapping = TextWrapping.Wrap;
baner.TextAlignment = TextAlignment.Center;
baner.VerticalAlignment = VerticalAlignment.Center;
pokaż wskazówkę
  • Przy wartościach wyliczeniowych w XAML zostaje tylko część po ostatniej kropce, np. Bold.
  • Brushes.Crimson w XAML to sama nazwa koloru.
ZAD 2Wizytówka w jednym napisie★☆☆

Zbuduj okno 360 × 200 z wizytówką: w pierwszej linii imię i nazwisko (rozmiar 22, pogrubione), w drugiej rola, np. „uczeń klasy 3 TP — technik programista” (kursywa, szara), po pustej linii adres e-mail (podkreślony, niebieski) i numer sali. Wszystko w jednym TextBlock, wyśrodkowane w oknie.

Wizytówka–□✕
Ola Nowak
uczennica klasy 3 TP — technik programista

ola.nowak@szkola.pl · sala 21

przykładowy wygląd

pokaż wskazówkę
  • Fragment z kilkoma własnymi ustawieniami (rozmiar, pogrubienie) najwygodniej zapisać jako Run.
  • Pusta linia to dwa LineBreak pod rząd.
ZAD 3Plakat koncertu★★☆

Zrób plakat szkolnego koncertu w oknie 400 × 500. Tło okna to pionowy gradient z trzech kolorów: na górze MidnightBlue, w połowie MediumPurple, na dole Pink. Na środku biały, wyśrodkowany tekst: tytuł „KONCERT JESIENNY” (rozmiar 32, pogrubiony), data i godzina, miejsce oraz przekreślona stara cena „15 zł” obok nowej „wstęp wolny”. W komentarzu zapisz, co się stanie, jeśli środkowy kolor dostanie Offset="0.2" — a potem sprawdź to.

pokaż wskazówkę
  • Gradient pionowy: zmienia się druga liczba punktów StartPoint i EndPoint. Trzy kolory to trzy GradientStop.
  • Przekreślenie fragmentu: TextDecorations="Strikethrough" na Run.
  • Biały kolor dla całego tekstu ustaw raz, na TextBlock.
ZAD 4Cytat dnia★★☆

Okno pokazuje „Cytat dnia” — inny w każdy dzień tygodnia. W kodzie przygotuj tablicę 7 krótkich cytatów i tablicę 7 autorów. Napis składa się z nagłówka „Cytat na poniedziałek:” (pogrubiony, nazwa dnia dobiera się sama), pustej linii, cytatu w kursywie i autora wyrównanego w tej samej linii po myślniku. Nagłówek, cytat i autor to trzy nazwane fragmenty Run, które wypełnia konstruktor. W komentarzu wyjaśnij, jak zamieniasz dzień tygodnia na indeks tablicy.

pokaż wskazówkę
  • DateTime.Now.DayOfWeek to wartość wyliczeniowa; rzutowana na int daje 0 dla niedzieli, 1 dla poniedziałku itd.
  • Polską nazwę dnia da DateTime.Now.ToString("dddd").
ZAD 5Ściągawka z operatorów★★☆

Zrób okno-ściągawkę z operatorami C#, które zawierają znaki specjalne XAML. Każda linia: operator czcionką Consolas (pogrubiony) i jego opis zwykłą czcionką, np. „&& — i (oba warunki prawdziwe)”, „<= — mniejsze lub równe”, „=> — strzałka w wyrażeniach lambda”, „" — cudzysłów zaczyna tekst”. Co najmniej 6 operatorów. Jeżeli projekt się nie kompiluje, w komentarzu zapisz, który znak spowodował błąd i jak go zapisałeś.

pokaż wskazówkę
  • Zajrzyj do tabeli encji w sekcji „Jak XAML czyta wartości”.
  • Krój pisma fragmentu ustawisz atrybutem FontFamily na Run.
ZAD 6Popraw cudzy XAML★★★

Poniższy plik ma sześć błędów. Przepisz go do projektu Plakat, popraw wszystkie i przy każdym zostaw komentarz z opisem. Gotowe okno ma mieć tło z gradientem od białego do jasnozielonego i wyśrodkowany, półprzezroczysty napis.

MainWindow.xaml
<Window x:Class="Plakat.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Plakat" Height=300 Width="400" Background="White">
    <window.Background>
        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
            <GradientStop Color="White" Offset="0"/>
            <GradientStop Color="LightGreen" Offset="1"/>
        </LinearGradientBrush>
    </window.Background>
    <TextBlock Text="Dzień Ziemi" FontSize="30" Opacity="0,8"
               HorizontalAlignment="Center" VerticalAlignment="Center">
        <Bold>22 kwietnia & cała szkoła</Bold>
    </TextBlock>
</Window>
pokaż wskazówkę
  • Sprawdź po kolei: cudzysłowy, wielkość liter w nazwie znacznika, właściwość ustawioną dwa razy (są takie dwie sytuacje), zapis ułamka i znak specjalny w tekście.
  • Gdy w napisie ma zostać i nazwa święta, i data, połącz je w jednej zawartości z LineBreak.
PODSUMOWANIE

Co trzeba zapamiętać

  • Znacznik XAML tworzy obiekt, atrybut ustawia jego właściwość — wszystko z XAML da się zrobić w C#.
  • XAML rozróżnia wielkość liter, wymaga zamykania znaczników i cudzysłowów.
  • Ułamki w XAML zawsze z kropką; znaki < > & " zapisuj encjami.
  • Napis z fragmentami: zawartość TextBlock z Run, Bold, Italic, LineBreak.
  • Enter w kodzie XAML między fragmentami to spacja, nie nowa linia.
  • Złożoną wartość zapisujesz jako element <Klasa.Właściwość>, np. gradient w <Window.Background>.

Dokumentacja: Microsoft Learn — XAML w WPF, klasa TextBlock.

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