C# · WPF · INF.04 · Kontrolki

TextBlock – wyświetlanie tekstu

Poznasz TextBlock – podstawową kontrolkę do wyświetlania tekstu w WPF. Nauczysz się ustawiać czcionkę, kolor, zawijanie tekstu oraz formatować fragmenty tekstu na różne sposoby.

TextBlock FontSize / FontWeight TextWrapping Inlines
1

Czym jest TextBlock?

TextBlock to kontrolka służąca wyłącznie do wyświetlania tekstu. Użytkownik nie może edytować jego zawartości – to tylko etykieta, napis, tytuł, komunikat.

TextBlock to nie TextBox!

TextBlock = wyświetla tekst, użytkownik nie może go zmieniać.
TextBox = pole do wpisywania tekstu przez użytkownika.

Prosta zasada: etykiety, opisy, wyniki obliczeń → TextBlock. Pola formularza do wypełnienia → TextBox.

TextBlock jest najczęściej używaną kontrolką tekstową w WPF – niemal każde okno ma ich kilkanaście. Warto go dobrze poznać.

Najprostszy TextBlock
<!-- Minimalny zapis -->
<TextBlock Text="Witaj, świecie!" />

<!-- Zapis z zawartością wewnątrz tagu -->
<TextBlock>Witaj, świecie!</TextBlock>

<!-- Oba zapisy dają identyczny efekt -->
2

Właściwości tekstu

Text i Foreground

Treść ustawiasz przez właściwość Text, a kolor tekstu przez Foreground.

Text i Foreground
<!-- Tekst z kolorem -->
<TextBlock Text="Błąd: nieprawidłowe dane"
           Foreground="Tomato" />

<!-- Kolor przez kod szesnastkowy -->
<TextBlock Text="Sukces!"
           Foreground="#2ecc71" />

<!-- Przydatne kolory dla statusów -->
<TextBlock Text="OK"      Foreground="MediumSeaGreen" />
<TextBlock Text="Błąd"   Foreground="Tomato"          />
<TextBlock Text="Uwaga"  Foreground="Gold"            />
<TextBlock Text="Info"   Foreground="SteelBlue"       />

Czcionka – font

TextBlock daje pełną kontrolę nad wyglądem czcionki. Oto wszystkie właściwości związane z czcionką:

WłaściwośćCo ustawiaPrzykładowe wartości
FontSizeRozmiar czcionki w punktach12, 16, 24, 48
FontWeightGrubość (pogrubienie)Normal, Bold, Light, ExtraBold
FontStyleKursywaNormal, Italic, Oblique
FontFamilyKrój pismaArial, Segoe UI, Consolas, Times New Roman
TextDecorationsDekoracjeUnderline, Strikethrough
Właściwości czcionki
<!-- Tytuł – duży, pogrubiony -->
<TextBlock Text="Wyniki egzaminu"
           FontSize="22"
           FontWeight="Bold"
           Foreground="White" />

<!-- Podtytuł – kursywa -->
<TextBlock Text="Rok szkolny 2024/2025"
           FontSize="14"
           FontStyle="Italic"
           Foreground="#aaa" />

<!-- Kod – font monospace -->
<TextBlock Text="Console.WriteLine("Hello")"
           FontFamily="Consolas"
           FontSize="13"
           Foreground="#a8ff78" />

<!-- Podkreślony -->
<TextBlock Text="Ważna informacja"
           TextDecorations="Underline" />

<!-- Przekreślony (np. stara cena) -->
<TextBlock Text="199 zł"
           TextDecorations="Strikethrough"
           Foreground="Gray" />

Wyrównanie tekstu

Tekst wewnątrz TextBlock możesz wyrównywać właściwością TextAlignment. To inne wyrównanie niż HorizontalAlignment – tamto dotyczy całej kontrolki w layoucie, to dotyczy treści wewnątrz niej.

TextAlignment – wyrównanie treści
<TextBlock Text="Do lewej"   TextAlignment="Left"    />
<TextBlock Text="Na środku"  TextAlignment="Center"  />
<TextBlock Text="Do prawej"  TextAlignment="Right"   />
<TextBlock Text="Justowanie – tekst wyrównany do obu krawędzi jednocześnie"
           TextAlignment="Justify"
           TextWrapping="Wrap" />
3

Zawijanie i przycinanie długiego tekstu

TextWrapping – zawijanie do nowej linii

Domyślnie TextBlock wyświetla tekst w jednej linii – jeśli jest za długi, po prostu wychodzi poza kontrolkę i jest obcinany. Właściwość TextWrapping zmienia to zachowanie.

WartośćZachowanie
NoWrap (domyślne)Tekst w jednej linii, nadmiar niewidoczny
WrapZawija do nowej linii w dowolnym miejscu
WrapWithOverflowZawija, ale długie słowa mogą wychodzić poza krawędź
TextWrapping
<!-- Bez zawijania – tekst obcięty -->
<TextBlock Text="To jest bardzo długi tekst który nie mieści się w jednej linii"
           Width="200"
           TextWrapping="NoWrap" />

<!-- Z zawijaniem – tekst przełamuje się do nowego wiersza -->
<TextBlock Text="To jest bardzo długi tekst który nie mieści się w jednej linii"
           Width="200"
           TextWrapping="Wrap" />

TextTrimming – trzykropek na końcu

Gdy tekst jest za długi i nie chcesz go zawijać, możesz zamiast tego pokazać trzykropek na końcu – tak jak w eksploratorze plików przy długich nazwach.

WartośćZachowanie
None (domyślne)Tekst po prostu obcięty, bez sygnalizacji
CharacterEllipsisObcina w połowie znaku i dodaje
WordEllipsisObcina na granicy słowa i dodaje
TextTrimming – trzykropek
<!-- Obcina na granicy słowa – czytelniej -->
<TextBlock Text="Bardzo długa nazwa pliku projektu końcowego.docx"
           Width="200"
           TextTrimming="WordEllipsis" />
<!-- Wyświetli: "Bardzo długa nazwa..." -->

<!-- Połączenie Wrap + Trimming: 2 linie max, reszta "..." -->
<TextBlock Text="Opis produktu który może być bardzo długi i wieloliniowy"
           Width="200"
           MaxHeight="40"
           TextWrapping="Wrap"
           TextTrimming="WordEllipsis" />
TextWrapping i TextTrimming nie działają razem wprost

Jeśli ustawisz TextWrapping="Wrap", tekst zawija się do nowych linii i TextTrimming nie przytnie go w poziomie. Żeby ograniczyć do konkretnej liczby linii, ustaw MaxHeight na TextBlock i użyj obu właściwości razem – nadmiar zostanie obcięty trzykropkiem.

4

Formatowanie fragmentów tekstu (Inlines)

Normalnie cały TextBlock ma jeden styl. Ale możesz też formatować poszczególne fragmenty tekstu inaczej – jeden fragment pogrubiony, inny w innym kolorze, jeszcze inny kursywą. Służą do tego elementy wewnętrzne zwane Inlines.

Run – zwykły fragment tekstu

Run to podstawowy element inline – po prostu fragment tekstu, któremu możesz nadać własny styl.

Run – fragmenty z różnymi stylami
<TextBlock>
    <Run Text="Wynik: " />
    <Run Text="42 punkty"
         Foreground="LimeGreen"
         FontWeight="Bold"
         FontSize="16" />
    <Run Text=" na 50 możliwych"
         Foreground="Gray" />
</TextBlock>
<!-- Wyświetli: Wynik: 42 punkty na 50 możliwych
     (każda część inaczej sformatowana) -->

Bold i Italic – szybkie pogrubienie i kursywa

Zamiast pisać <Run FontWeight="Bold"> możesz użyć skróconych elementów <Bold> i <Italic>.

Bold, Italic i ich kombinacje
<TextBlock>
    Zamówienie nr
    <Bold>#2024/11/001</Bold>
    zostało
    <Italic>przyjęte do realizacji</Italic>
    i będzie gotowe
    <Bold><Italic>jutro do 12:00</Italic></Bold>.
</TextBlock>

<!-- Inne przydatne: Underline, Strikethrough -->
<TextBlock>
    Stara cena:
    <Run TextDecorations="Strikethrough" Foreground="Gray"
         Text="199 zł" />
    Nowa cena:
    <Bold><Run Foreground="Tomato" Text="149 zł"></Run></Bold>
</TextBlock>

LineBreak – nowa linia

<LineBreak /> wstawia twardy znak nowej linii – jak naciśnięcie Enter w edytorze tekstu.

LineBreak – przełamanie linii
<TextBlock>
    Imię i nazwisko: <Bold>Jan Kowalski</Bold>
    <LineBreak />
    Klasa: <Bold>4TI</Bold>
    <LineBreak />
    Wynik: <Run Foreground="LimeGreen" FontWeight="Bold"
               Text="ZALICZONY" />
</TextBlock>

Span – własne style dla fragmentu

Span to kontener dla Inlines – możesz obejmować nim kilka elementów i nadawać im wspólny styl.

Span – grupowanie fragmentów
<TextBlock>
    Status:
    <Span Foreground="LimeGreen"
          FontWeight="Bold"
          FontSize="14">
        Aktywny
    </Span>
    | Ostatnie logowanie:
    <Span Foreground="SteelBlue">
        2024-11-15 14:32
    </Span>
</TextBlock>

Hyperlink – klikalny link

Hyperlink tworzy klikalny link wewnątrz TextBlock. Po kliknięciu możesz obsłużyć zdarzenie Click.

Hyperlink w TextBlock
<TextBlock>
    Więcej informacji na
    <Hyperlink Click="Link_Click">naszej stronie</Hyperlink>.
</TextBlock>

// C# – obsługa kliknięcia linku
private void Link_Click(object sender, RoutedEventArgs e)
{
    // Otwieramy stronę w domyślnej przeglądarce
    System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
    {
        FileName        = "https://school-it.pl",
        UseShellExecute = true
    });
}
5

TextBlock w C#

Zmiana właściwości z kodu

Wszystkie właściwości TextBlock możesz zmieniać z kodu C# w czasie działania programu – zmiana koloru po błędzie, aktualizacja wyniku po obliczeniu itp.

Typowe operacje na TextBlock z C#
// Zmiana tekstu
lblWynik.Text = "Obliczono: 42";

// Zmiana koloru tekstu
lblStatus.Foreground = Brushes.Tomato;
lblStatus.Foreground = new SolidColorBrush(Color.FromRgb(46, 204, 113));

// Zmiana rozmiaru czcionki
lblTytul.FontSize = 24;

// Pogrubienie i kursywa
lblTytul.FontWeight = FontWeights.Bold;
lblTytul.FontStyle  = FontStyles.Italic;

// Ukrycie / pokazanie
lblBlad.Visibility = Visibility.Collapsed;  // ukryj
lblBlad.Visibility = Visibility.Visible;    // pokaż

// Typowy wzorzec: pokazanie komunikatu błędu
private void PokazBlad(string komunikat)
{
    lblBlad.Text       = komunikat;
    lblBlad.Foreground = Brushes.Tomato;
    lblBlad.Visibility = Visibility.Visible;
}

private void PokazSukces(string komunikat)
{
    lblBlad.Text       = komunikat;
    lblBlad.Foreground = Brushes.LimeGreen;
    lblBlad.Visibility = Visibility.Visible;
}

Formatowanie Inlines z C#

Możesz też budować złożone formatowanie (Inlines) programowo z C#. Przydaje się gdy treść pochodzi z danych, a nie jest znana z góry.

Dynamiczne Inlines z C#
private void WyswietlWynik(string imie, int punkty, int max)
{
    // Czyścimy poprzednią zawartość
    lblWynik.Inlines.Clear();

    // Budujemy nową zawartość fragment po fragmencie
    lblWynik.Inlines.Add(new Run($"Uczeń: "));

    Bold boldImie = new Bold(new Run(imie));
    lblWynik.Inlines.Add(boldImie);

    lblWynik.Inlines.Add(new Run($"  |  Wynik: "));

    Run runPunkty = new Run($"{punkty}/{max}");
    runPunkty.Foreground = punkty >= max / 2 ? Brushes.LimeGreen : Brushes.Tomato;
    runPunkty.FontWeight = FontWeights.Bold;
    lblWynik.Inlines.Add(runPunkty);
}
6

TextBlock vs Label – co kiedy wybrać?

WPF ma dwie kontrolki do wyświetlania tekstu: TextBlock i Label. Wyglądają podobnie, ale są różnice.

CechaTextBlockLabel
Skrót klawiszowy (Alt+X)❌ Brak✅ Przez właściwość Target
Formatowanie fragmentów (Inlines)✅ Pełne wsparcie❌ Brak
Zawijanie tekstu✅ TextWrapping⚠️ Tylko przez zagnieżdżony TextBlock
Lekki / wydajny✅ Lżejszy➖ Trochę cięższy (dziedziczy po ContentControl)
Zwykłe etykiety w formularzu✅ Wystarczy✅ Też ok
Praktyczna zasada

Używaj TextBlock do wyświetlania tekstu w 95% przypadków – wyniki, opisy, statusy, tytuły.
Używaj Label tylko gdy potrzebujesz skrótu klawiszowego do pola formularza (Target="{Binding ElementName=txtImie}").

Label z Target – skrót klawiszowy
<Label Content="_Imię:"
       Target="{Binding ElementName=txtImie}" />
<TextBox x:Name="txtImie" />
<!-- Naciśnięcie Alt+I przeniesie focus do pola txtImie -->
<!-- Podkreślnik _ przed literą oznacza skrót -->
7

Praktyczne przykłady

Karta profilu ucznia

Karta z mixed formatowaniem
<Border Background="#252535"
        CornerRadius="8"
        Padding="16"
        Width="280">
    <StackPanel>

        <!-- Imię i nazwisko -->
        <TextBlock FontSize="20"
                   FontWeight="Bold"
                   Foreground="White"
                   Margin="0,0,0,4">
            Jan Kowalski
        </TextBlock>

        <!-- Klasa -->
        <TextBlock Foreground="#888"
                   Margin="0,0,0,12">
            Klasa <Bold><Run Foreground="SteelBlue"
                            Text="4TI"></Run></Bold>
            · nr albumu <Bold>2024/042</Bold>
        </TextBlock>

        <!-- Wynik -->
        <TextBlock Foreground="White">
            Wynik egzaminu:
            <Run Text="46/50"
                 Foreground="LimeGreen"
                 FontWeight="Bold"
                 FontSize="16" />
            <Run Text=" (92%)"
                 Foreground="#888" />
        </TextBlock>

    </StackPanel>
</Border>

Komunikat statusu z ikoną

Dynamiczny komunikat statusu – C#
// XAML: <TextBlock x:Name="lblStatus" FontSize="13" />

private void UstawStatus(string ikona, string tekst, Brush kolor)
{
    lblStatus.Inlines.Clear();

    Run runIkona = new Run(ikona + "  ");
    runIkona.Foreground = kolor;

    Run runTekst = new Run(tekst);
    runTekst.Foreground = kolor;

    lblStatus.Inlines.Add(runIkona);
    lblStatus.Inlines.Add(runTekst);
}

// Użycie:
UstawStatus("✅", "Zapisano pomyślnie",          Brushes.LimeGreen);
UstawStatus("❌", "Błąd: nieprawidłowy format",   Brushes.Tomato);
UstawStatus("⚠️", "Uwaga: brak danych",            Brushes.Gold);
UstawStatus("🔄", "Ładowanie...",                  Brushes.SteelBlue);
8

Częste błędy

❌ Błąd 1: Próba edytowania TextBlock przez użytkownika

❌ Zły wybór kontrolki

<TextBlock x:Name="tbImie" />
<!-- Użytkownik nie może
     wpisać tekstu w TextBlock!
     Do formularzy użyj TextBox -->

✅ TextBox do wpisywania

<!-- Wpisywanie przez użytkownika: -->
<TextBox x:Name="txtImie" />

<!-- Wyświetlanie wyniku: -->
<TextBlock x:Name="lblWynik" />

❌ Błąd 2: Mixowanie Text= z Inlines

❌ Text i Inlines nie mogą istnieć razem

<TextBlock Text="Wynik: ">
    <Bold>42</Bold>
    <!-- Błąd! Nie można mieć
         jednocześnie Text=""
         i elementów Inline -->
</TextBlock>

✅ Albo Text=, albo Inlines

<!-- Tylko Inlines (bez Text=): -->
<TextBlock>
    <Run Text="Wynik: " />
    <Bold>42</Bold>
</TextBlock>

❌ Błąd 3: Długi tekst bez TextWrapping

❌ Tekst wychodzi poza kontrolkę

<TextBlock
    Text="Bardzo długi opis produktu
          który nie mieści się w kolumnie"
    Width="150" />
<!-- Tekst obcięty, reszta niewidoczna -->

✅ Dodaj TextWrapping

<TextBlock
    Text="Bardzo długi opis produktu
          który nie mieści się w kolumnie"
    Width="150"
    TextWrapping="Wrap" />

❌ Błąd 4: Zmiana Inlines bez Clear()

❌ Inlines narastają przy każdym kliknięciu

private void btn_Click(...)
{
    // Brak Clear() – za każdym
    // kliknięciem dodają się
    // kolejne fragmenty!
    lblWynik.Inlines.Add(new Run("nowy"));
}

✅ Wyczyść przed aktualizacją

private void btn_Click(...)
{
    lblWynik.Inlines.Clear(); // najpierw
    lblWynik.Inlines.Add(new Run("nowy"));
}
9

Zadania do wykonania

Zadanie 1 łatwe

Stwórz okno z pięcioma TextBlockami ułożonymi w StackPanel. Każdy ma inny rozmiar, styl i kolor – jakby tytuł, podtytuł, tekst główny, etykieta stanu i mała nota stopki. Jeden z nich ma tekst przekreślony (stara cena), inny podkreślony.

Zadanie 2 łatwe

Zbuduj formularz: pole TextBox na imię, TextBox na wiek, przycisk „Sprawdź”. Po kliknięciu wyświetl w TextBlock z Inlines odpowiedź w stylu:
„Cześć, Ania! Masz 17 lat. Jesteś niepełnoletnia.”
Słowo „pełnoletni” / „niepełnoletnia” zmieniaj kolor na zielony lub czerwony w zależności od wieku.

Zadanie 3 średnie

Stwórz prostą kartę produktu w Border: nazwa produktu (duży, pogrubiony), opis (zawijany, szary, max 3 linie), cena (przekreślona stara + nowa zielona), przycisk „Do koszyka”. Wszystko w XAML – żadnych Inlines z C#. Użyj TextWrapping="Wrap" i TextTrimming="WordEllipsis" na opisie.

Zadanie 4 średnie

Stwórz kalkulator BMI. Dwa pola TextBox (waga kg, wzrost cm) i przycisk „Oblicz”. Wynik wyświetl w TextBlock z Inlines: wartość BMI pogrubiona w kolorze zależnym od wyniku (niebieski – niedowaga, zielony – norma, pomarańczowy – nadwaga, czerwony – otyłość), obok kategoria tekstem kursywą. Użyj metody UstawStatus lub podobnej pomocniczej metody.