Dataniedziela, 9 sierpnia 2026 Czas07:55:21
← Aplikacje desktopowe (WPF)

Lekcja 6. Kontrolki I — Button, TextBox, Label/TextBlock

Średni

Po co się tego uczymy?

"Taki Button — ile ma właściwości?" To pytanie, na które ta lekcja odpowiada wyczerpująco: poznasz PEŁNY zestaw właściwości trzech najczęściej używanych kontrolek — przycisku, pola tekstowego i etykiety — razem z ich odpowiednikami w Windows Forms (bo egzamin INF.04 może odwoływać się do obu technologii). To realizacja INF.04.5.3 ("programuje desktopowe aplikacje z wykorzystaniem kontrolek").

Teoria

W WPF każda kontrolka ma dziesiątki właściwości — nie musisz znać wszystkich na pamięć, ale musisz wiedzieć, gdzie szukać (okno Properties z poprzedniej lekcji) i jakie są te najważniejsze, używane praktycznie w każdej aplikacji.

Button (WPF) / Button (Windows Forms) — przycisk

Właściwość WPF Odpowiednik Windows Forms Opis
Content Text Tekst (lub dowolna zawartość — w WPF nawet obrazek) wyświetlany na przycisku.
IsEnabled Enabled Włącza (true) lub wyłącza (false, przycisk wyszarzony i nieklikalny) przycisk.
Visibility Visible W WPF przyjmuje wartość Visible, Hidden (niewidoczny, ale zajmuje miejsce) albo Collapsed (niewidoczny, nie zajmuje miejsca). W Forms to prosta wartość logiczna.
Background BackColor Kolor tła przycisku.
Foreground ForeColor Kolor tekstu.
FontSize, FontWeight, FontFamily Font Styl i rozmiar czcionki (w WPF rozbite na osobne właściwości, w Forms jeden obiekt Font).
Width, Height Width, Height Wymiary przycisku w pikselach niezależnych od rozdzielczości.
Command — (brak odpowiednika) Alternatywa dla zdarzenia Click — łączy przycisk z metodą w ViewModelu zamiast w code-behind. Poznasz szczegółowo w lekcji o obsłudze zdarzeń i w dziale MVVM.

Obsługa kliknięcia w Windows Forms wygląda tak:

private void btnZapisz_Click(object sender, EventArgs e)
{
    labelWynik.Text = "Dane zapisane!";
}

TextBox (WPF i Windows Forms) — pole tekstowe

Właściwość WPF Odpowiednik Windows Forms Opis
Text Text Zawartość pola — string, który wpisuje użytkownik.
MaxLength MaxLength Maksymalna liczba znaków, jaką można wpisać.
AcceptsReturn + wysokość > 1 wiersza Multiline Pozwala pisać tekst w kilku liniach zamiast jednej.
IsReadOnly ReadOnly Pole tylko do odczytu — użytkownik widzi tekst, ale nie może go zmienić.
osobna kontrolka PasswordBox PasswordChar Ukrywanie wpisywanych znaków (hasła). W WPF to CAŁKOWICIE inna kontrolka, nie właściwość TextBoxa.
TextWrapping (automatyczne przy Multiline) Zawijanie tekstu w polu wielowierszowym.

W WPF pole tekstowe najczęściej łączy się z danymi przez data binding, zamiast ręcznie odczytywać Text przy każdym kliknięciu:

<TextBox Text="{Binding Imie, UpdateSourceTrigger=PropertyChanged}" />

Do pełnego bindingu (aktualizacja obiektu w tle na bieżąco) wrócimy przy okazji MVVM — w tej lekcji budujemy prostszą wersję, opartą na zdarzeniach, którą i tak musisz znać, bo bywa szybsza w małych aplikacjach.

Label / TextBlock — wyświetlanie tekstu

W WPF do wyświetlania tekstu (bez możliwości edycji przez użytkownika) służy najczęściej TextBlock — lżejsza kontrolka niż odziedziczony po Windows Forms Label (WPF też ma swój Label, używany rzadziej, głównie jako podpis obok innej kontrolki, np. z ustawionym Target).

Właściwość WPF (TextBlock) Odpowiednik Windows Forms (Label) Opis
Text Text Wyświetlany tekst.
(rozmiar dopasowuje się automatycznie) AutoSize W Forms trzeba jawnie włączyć dopasowanie rozmiaru etykiety do treści — w WPF to zachowanie domyślne.
Foreground ForeColor Kolor tekstu.
Background BackColor Kolor tła.
FontSize, FontWeight Font, TextAlign Styl czcionki i (w Forms) wyrównanie tekstu wewnątrz etykiety.
TextWrapping (zależne od AutoSize) Zawijanie długiego tekstu do kolejnej linii.

Przykład w Windows Forms — ustawienie tekstu etykiety z kodu: lblWynik.Text = "Witaj, " + txtImie.Text + "!"; W WPF ten sam efekt osiąga się albo przez binding (<TextBlock Text="{Binding Wynik}" />), albo — w prostszym, event-based podejściu tej lekcji — bezpośrednim przypisaniem w code-behind, identycznie jak w Forms.

Schemat

Mapa wlasciwosci: WPF -> Windows Forms

Button:
  Content -> Text | IsEnabled -> Enabled | Visibility -> Visible
  Background -> BackColor | Foreground -> ForeColor

TextBox:
  Text -> Text | MaxLength -> MaxLength | IsReadOnly -> ReadOnly
  PasswordBox (osobna kontrolka) -> PasswordChar

TextBlock / Label:
  Text -> Text | Foreground -> ForeColor | Background -> BackColor

Przykład z życia

Formularz kontaktowy na stronie internetowej (imię, e-mail, przycisk "Wyślij") to dokładnie ten sam zestaw kontrolek co w aplikacji desktopowej — pole tekstowe do wpisania danych, etykieta pokazująca wynik lub błąd walidacji, przycisk uruchamiający akcję. Różni się tylko technologia (HTML zamiast XAML), ale koncepcja "kontrolka ma właściwości, które ustawiasz, i zdarzenia, na które reagujesz" jest uniwersalna w każdym interfejsie graficznym — również tym, który znasz z INF.03.

MainWindow.xaml

<Window x:Class="KontrolkiApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Formularz powitania" Height="220" Width="360">
    <StackPanel Margin="20">
        <TextBlock Text="Podaj swoje imię:" Margin="0,0,0,5"/>
        <TextBox x:Name="PoleImie"
                 MaxLength="30"
                 TextChanged="PoleImie_TextChanged"/>

        <TextBlock x:Name="EtykietaLicznik"
                    Text="Długość: 0 znaków"
                    Foreground="Gray"
                    Margin="0,5,0,15"/>

        <Button x:Name="PrzyciskPrzywitaj"
                Content="Przywitaj się"
                IsEnabled="False"
                Click="PrzyciskPrzywitaj_Click"/>

        <TextBlock x:Name="EtykietaWynik"
                    Text=""
                    FontSize="16"
                    FontWeight="Bold"
                    Foreground="DarkGreen"
                    Margin="0,15,0,0"/>
    </StackPanel>
</Window>

MainWindow.xaml.cs

using System.Windows;
using System.Windows.Controls;

namespace KontrolkiApp
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void PoleImie_TextChanged(object sender, TextChangedEventArgs e)
        {
            int dlugosc = PoleImie.Text.Length;
            EtykietaLicznik.Text = $"Długość: {dlugosc} znaków";

            // Przycisk wlacza sie dopiero, gdy uzytkownik cos wpisal
            PrzyciskPrzywitaj.IsEnabled = dlugosc > ;
        }

        private void PrzyciskPrzywitaj_Click(object sender, RoutedEventArgs e)
        {
            EtykietaWynik.Text = $"Witaj, {PoleImie.Text}!";
        }
    }
}

Komentarz i wyjaśnienie kodu

Plik MainWindow.xaml definiuje sam wygląd — pole tekstowe z limitem 30 znaków (MaxLength), etykietę pokazującą licznik znaków, przycisk startowo wyłączony (IsEnabled="False") i etykietę na wynik. Zwróć uwagę, że każda kontrolka, do której chcemy się odwołać w kodzie C#, MUSI mieć nadane x:Name — to jest dokładnie ten identyfikator, po którym odwołujemy się do niej w pliku .xaml.cs.

Plik MainWindow.xaml.cs zawiera dwie metody obsługi zdarzeń. PoleImie_TextChanged uruchamia się przy KAŻDEJ zmianie tekstu w polu (czyli przy każdym wciśniętym klawiszu) — aktualizuje licznik znaków i włącza przycisk, gdy pole nie jest puste. PrzyciskPrzywitaj_Click uruchamia się po kliknięciu i wypisuje spersonalizowane powitanie. Zauważ, że w XAML nazwy tych metod (TextChanged="PoleImie_TextChanged", Click="PrzyciskPrzywitaj_Click") muszą DOKŁADNIE odpowiadać nazwom metod w code-behind — literówka tutaj to jeden z najczęstszych błędów początkujących.

Ćwiczenie samodzielne

Utwórz nowy projekt WPF, wklej powyższy XAML do MainWindow.xaml i kod C# do MainWindow.xaml.cs (pamiętaj, żeby zmienić x:Class na nazwę Twojego projektu). Uruchom aplikację, wpisz swoje imię i sprawdź, czy licznik znaków aktualizuje się na bieżąco, a przycisk włącza się dopiero po wpisaniu choć jednej litery.

Zadania do pracy własnej

  1. Dodaj drugie pole TextBox (Nazwisko) i rozbuduj powitanie, żeby wyświetlało zarówno imię, jak i nazwisko.

  2. Dodaj do formularza właściwość Background zmieniającą kolor tła EtykietaWynik na jasnozielony w momencie wyświetlenia powitania (ustaw tę właściwość w kodzie C#, w metodzie PrzyciskPrzywitaj_Click).

  3. Zbuduj formularz rejestracji z trzema polami TextBox (Imię, Nazwisko, Wiek) i przyciskiem 'Zarejestruj'. Przycisk ma być IsEnabled="False" dopóki WSZYSTKIE trzy pola nie są wypełnione (podpięcie TextChanged pod każde z trzech pól, sprawdzające ich łączny stan). Po kliknięciu wyświetl podsumowanie w TextBlock, a pole Wiek spróbuj sparsować przez int.TryParse — jeśli się nie uda, pokaż czerwony komunikat błędu zamiast podsumowania.

Typowe błędy

Brak x:Name na kontrolce — bez tego atrybutu nie da się odwołać do kontrolki z kodu C#, kompilator zgłosi błąd "nie istnieje w bieżącym kontekście".

Niezgodność nazwy metody w XAML i code-behind — jeśli w Click="PrzyciskZapisz_Click" jest literówka względem nazwy metody w pliku .cs, aplikacja się nie skompiluje.

Mylenie Content (WPF) z Text — początkujący często próbują ustawić Text="OK" na przycisku (co jest poprawne w Windows Forms), podczas gdy w WPF przycisk używa właściwości Content.

Zapominanie o UpdateSourceTrigger przy bindingu — domyślnie TextBox aktualizuje powiązaną właściwość dopiero po utracie fokusu, nie przy każdym znaku — jeśli oczekujesz reakcji "na żywo", trzeba jawnie dodać UpdateSourceTrigger=PropertyChanged.

Nawiązanie do egzaminu zawodowego

To realizacja INF.04.5.3 — "programuje desktopowe aplikacje okienkowe z wykorzystaniem kontrolek". Button, TextBox i TextBlock/Label to absolutny fundament każdego formularza WPF — pojawią się w praktycznie każdym kolejnym zadaniu w tym dziale.