Kontrolki WPF-TextBlock

1. Czym są kontrolki w WPF?

Kontrolki w WPF to gotowe komponenty interfejsu użytkownika, które hermetyzują określoną funkcjonalność i sposób wyświetlania. Każda kontrolka to klasa w frameworku .NET, która dziedziczy ostatecznie po klasie Control lub jej pochodnych. Ta hierarchia dziedziczenia oznacza, że wszystkie kontrolki współdzielą pewne podstawowe cechy i zachowania, ale każda ma też swoje unikalne właściwości.

Kontrolki w WPF różnią się fundamentalnie od tradycyjnych kontrolek Windows Forms. Są one w pełni konfigurowalną reprezentacją elementów interfejsu, gdzie można modyfikować nie tylko właściwości jak kolor czy rozmiar, ale także kompletnie zmienić sposób ich renderowania zachowując funkcjonalność. To oznacza, że przycisk może wyglądać jak tradycyjny przycisk, ale równie dobrze może być okrągły, gradientowy, animowany, czy nawet przypominać obrazek – pozostając przy tym w pełni funkcjonalnym przyciskiem.

Architektura kontrolek WPF opiera się na kilku kluczowych koncepcjach. Po pierwsze, każda kontrolka ma swój szablon wizualny (template), który określa jej wygląd. Po drugie, kontrolki obsługują system stylów, który pozwala na globalne definiowanie wyglądu. Po trzecie, wszystkie kontrolki uczestniczą w systemie layoutu, co oznacza, że automatycznie dostosowują się do dostępnej przestrzeni i zmieniają położenie względem innych elementów.

2. Anatomia kontrolki – co robi kontrolka?

Każda kontrolka WPF pełni kilka podstawowych funkcji, które można podzielić na kategorie odpowiedzialności. Pierwszą i najbardziej oczywistą jest renderowanie – kontrolka musi potrafić narysować się na ekranie w sposób odpowiadający swojemu przeznaczeniu i aktualnym właściwościom. Ta funkcjonalność jest obsługiwana przez system szablonów i silnik renderowania WPF.

Drugą kluczową funkcją jest obsługa interakcji użytkownika. Kontrolki reagują na zdarzenia myszy, klawiatury i innych urządzeń wejściowych, przekształcając fizyczne działania użytkownika w logiczne zdarzenia aplikacji. Na przykład, gdy użytkownik kliknie na przycisk, kontrolka przycisk wykrywa to kliknięcie i wywołuje zdarzenie Click, które może być obsłużone przez kod aplikacji.

Trzecią funkcją jest zarządzanie stanem. Kontrolki muszą pamiętać i zarządzać swoim wewnętrznym stanem – czy przycisk jest naciśnięty, czy pole tekstowe ma fokus, jaki tekst jest aktualnie wyświetlany. Ten stan wpływa zarówno na wygląd kontrolki, jak i na sposób, w jaki reaguje na interakcje.

Czwartą funkcją jest udział w systemie layoutu. Kontrolki muszą potrafić komunikować się z kontenerami nadrzędnymi, informując o swoich preferencjach dotyczących rozmiaru i pozycji, oraz reagować na zmiany dostępnej przestrzeni poprzez odpowiednie przeskalowanie czy repositioning.

3. Właściwości kontrolek – jak je zmieniać?

System właściwości w WPF jest znacznie bardziej zaawansowany niż w tradycyjnych technologiach. WPF wprowadza koncepcję Dependency Properties – właściwości, które nie tylko przechowują wartości, ale także obsługują zaawansowane funkcjonalności jak data binding, animacje, style i dziedziczenie wartości.

Właściwości można modyfikować na kilka sposobów. Najprostszym jest bezpośrednie ustawienie w XAML podczas definiowania kontrolki. Ta metoda jest idealna dla wartości statycznych, które nie zmieniają się podczas działania aplikacji. W kodzie C# właściwości można modyfikować zarówno podczas inicjalizacji, jak i dynamicznie w odpowiedzi na zdarzenia lub logikę biznesową.

System stylów pozwala na definiowanie właściwości w sposób bardziej globalny. Style działają podobnie do CSS w świecie webowym – można zdefiniować zestaw właściwości raz, a następnie aplikować go do wielu kontrolek. To podejście zapewnia spójność wizualną i ułatwia wprowadzanie zmian w wyglądzie aplikacji.

Data binding to kolejny sposób ustawiania właściwości, gdzie wartość pochodzi z zewnętrznego źródła danych i jest automatycznie synchronizowana. Animacje pozwalają na płynne przejścia między wartościami właściwości w czasie, tworząc efekty wizualne, które poprawiają doświadczenie użytkownika.

4. TextBlock – pierwsza kontrolka w praktyce

TextBlock to jedna z najprostszych, ale jednocześnie najważniejszych kontrolek w WPF. Jej podstawowym przeznaczeniem jest wyświetlanie tekstu tylko do odczytu. W przeciwieństwie do TextBox, TextBlock nie pozwala użytkownikowi na edycję treści, co czyni go idealnym do wyświetlania etykiet, nagłówków, opisów i innej informacji tekstowej.

Prostota TextBlock nie oznacza ograniczonej funkcjonalności. Kontrolka ta oferuje zaawansowane możliwości formatowania tekstu, obsługę różnych czcionek, kolorów, stylów i efektów. Może wyświetlać tekst w wielu liniach, obsługiwać automatyczne zawijanie tekstu oraz różne sposoby wyrównywania.

Podstawowe użycie TextBlock

Najprostsze zastosowanie TextBlock to wyświetlenie statycznego tekstu:

<TextBlock Text="Witaj w aplikacji WPF!"/>

Ten minimalny przykład utworzy kontrolkę wyświetlającą podany tekst z domyślnymi ustawieniami formatowania. Tekst zostanie wyrenderowany czarną czcionką systemową w rozmiarze domyślnym dla aplikacji.

Właściwość Text jest głównym sposobem przekazywania treści do TextBlock. Można ją ustawiać zarówno w XAML jak atrybutem, jak i programowo w kodzie C#:

txtBlock.Text = "Nowy tekst ustawiony z kodu";

Formatowanie tekstu w TextBlock

TextBlock oferuje bogaty zestaw właściwości do formatowania tekstu. Podstawowe właściwości typograficzne pozwalają kontrolować wygląd czcionki:

<TextBlock Text="Formatowany tekst" 
           FontFamily="Arial" 
           FontSize="16" 
           FontWeight="Bold" 
           FontStyle="Italic"/>

Właściwość FontFamily określa rodzinę czcionek do użycia. Można podać nazwę konkretnej czcionki zainstalowanej w systemie, lub użyć nazw generycznych jak „Serif”, „Sans-Serif” czy „Monospace”. WPF automatycznie wybierze najlepiej pasującą czcionkę dostępną w systemie.

FontSize kontroluje rozmiar tekstu. Wartość jest podawana w jednostkach niezależnych od urządzenia (device-independent units), co oznacza, że tekst będzie miał odpowiedni rozmiar niezależnie od rozdzielczości ekranu.

FontWeight określa grubość czcionki. Można używać wartości predefiniowanych jak Normal, Bold, Light, lub numerycznych od 100 do 900, gdzie 400 odpowiada normalnej grubości, a 700 to bold.

FontStyle pozwala na ustawienie stylu czcionki – Normal, Italic lub Oblique.

Kolory i efekty wizualne

TextBlock obsługuje zaawansowane opcje kolorystyczne i efekty wizualne:

<TextBlock Text="Kolorowy tekst z efektami" 
           Foreground="DarkBlue" 
           Background="LightYellow"
           TextDecorations="Underline">
    <TextBlock.Effect>
        <DropShadowEffect Color="Gray" ShadowDepth="2"/>
    </TextBlock.Effect>
</TextBlock>

Właściwość Foreground określa kolor tekstu. Można używać nazw predefiniowanych kolorów, wartości szesnastkowych (#FF0000 dla czerwonego), lub tworzyć bardziej zaawansowane pędzle z gradientami.

Background ustawia kolor tła kontrolki. Przydatne gdy chcemy wyróżnić fragment tekstu lub utworzyć efekt podobny do zakreślacza.

TextDecorations pozwala na dodawanie dekoracji tekstowych jak podkreślenie (Underline), przekreślenie (Strikethrough), lub linia nad tekstem (Overline).

Efekty wizualne, jak DropShadowEffect pokazany w przykładzie, dodają trójwymiarowy wygląd tekstu z cieniami, rozmyciem lub innymi efektami graficznymi.

Wyrównywanie i pozycjonowanie tekstu

Kontrola nad pozycjonowaniem tekstu w TextBlock jest bardzo elastyczna:

<TextBlock Text="Wyrównany tekst" 
           HorizontalAlignment="Center" 
           VerticalAlignment="Top" 
           TextAlignment="Center" 
           Width="200" 
           Height="100"/>

HorizontalAlignment i VerticalAlignment kontrolują pozycję całej kontrolki TextBlock względem jej kontenera nadrzędnego. TextAlignment natomiast określa, jak tekst jest wyrównywany wewnątrz samej kontrolki TextBlock.

To rozróżnienie jest ważne – kontrolka może być wyśrodkowana w kontenerze (HorizontalAlignment="Center"), ale tekst wewnątrz niej może być wyrównany do lewej (TextAlignment="Left").

Obsługa długiego tekstu

TextBlock radzi sobie dobrze z długimi tekstami oferując kilka mechanizmów ich obsługi:

<TextBlock Text="To jest bardzo długi tekst, który może nie zmieścić się w jednej linii i wymagać specjalnej obsługi" 
           Width="200" 
           TextWrapping="Wrap" 
           TextTrimming="CharacterEllipsis"/>

TextWrapping określa, czy tekst ma być zawijany do nowych linii gdy nie mieści się w dostępnej szerokości. Wartość Wrap włącza automatyczne zawijanie, NoWrap je wyłącza.

TextTrimming kontroluje sposób obsługi tekstu, który nie mieści się w dostępnej przestrzeni. CharacterEllipsis dodaje „…” na końcu widocznego tekstu, informując użytkownika, że jest więcej treści. WordEllipsis działa podobnie, ale przycina na granicy słów.

Wykorzystanie praktyczne TextBlock

W rzeczywistych aplikacjach TextBlock najczęściej służy do wyświetlania etykiet, nagłówków i informacji opisowych. Oto kilka typowych scenariuszy użycia:

Nagłówki sekcji:

<TextBlock Text="Ustawienia aplikacji" 
           FontSize="20" 
           FontWeight="Bold" 
           Margin="0,0,0,15" 
           Foreground="DarkBlue"/>

Komunikaty informacyjne:

<TextBlock Text="Operacja zakończona pomyślnie. Dane zostały zapisane." 
           Foreground="Green" 
           Background="LightGreen" 
           Padding="10" 
           TextWrapping="Wrap"/>