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.
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 = 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ć.
<!-- Minimalny zapis --> <TextBlock Text="Witaj, świecie!" /> <!-- Zapis z zawartością wewnątrz tagu --> <TextBlock>Witaj, świecie!</TextBlock> <!-- Oba zapisy dają identyczny efekt -->
Właściwości tekstu
Text i Foreground
Treść ustawiasz przez właściwość Text,
a kolor tekstu przez 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 ustawia | Przykładowe wartości |
|---|---|---|
FontSize | Rozmiar czcionki w punktach | 12, 16, 24, 48 |
FontWeight | Grubość (pogrubienie) | Normal, Bold, Light, ExtraBold |
FontStyle | Kursywa | Normal, Italic, Oblique |
FontFamily | Krój pisma | Arial, Segoe UI, Consolas, Times New Roman |
TextDecorations | Dekoracje | Underline, Strikethrough |
<!-- 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.
<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" />
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 |
Wrap | Zawija do nowej linii w dowolnym miejscu |
WrapWithOverflow | Zawija, ale długie słowa mogą wychodzić poza krawędź |
<!-- 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 |
CharacterEllipsis | Obcina w połowie znaku i dodaje … |
WordEllipsis | Obcina na granicy słowa i dodaje … |
<!-- 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" />
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.
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.
<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>.
<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.
<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.
<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.
<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 }); }
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.
// 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.
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); }
TextBlock vs Label – co kiedy wybrać?
WPF ma dwie kontrolki do wyświetlania tekstu: TextBlock
i Label. Wyglądają podobnie, ale są różnice.
| Cecha | TextBlock | Label |
|---|---|---|
| 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 |
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 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 -->
Praktyczne przykłady
Karta profilu ucznia
<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ą
// 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);
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"));
}
Zadania do wykonania
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.
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.
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.
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.