Podstawowe kontrolki i obsługa zdarzeń w Visual Studio 2022 – Windows Forms i WPF (.NET 8/9)

Każda aplikacja reaguje na działania użytkownika – kliknięcie przycisku, wpisanie tekstu, zmianę suwaka czy wybór z listy.
To właśnie zdarzenia.
W tym artykule zobaczysz, jak działają one w dwóch środowiskach: Windows Forms i WPF.
Oba wykorzystują język C#, ale sposób podpinania kodu i niektóre właściwości kontrolek różnią się.


Windows Forms a WPF – dwie drogi do tego samego celu

  • Windows Forms – prostsze w obsłudze, każdy przycisk ma swój kod w tle (tzw. eventy).
    Kod jest bezpośrednio przypięty do przycisku lub pola, np. button1_Click.
  • WPF – nowoczesne rozwiązanie oparte na XAML.
    Tu oprócz eventów można używać komend (Command), czyli poleceń, które łączą przycisk z metodą w logice programu (ViewModelu).
    Dzięki temu UI i logika są od siebie oddzielone, co jest ważne przy większych projektach lub egzaminie INF.04.

Przycisk (Button)

To najczęściej używana kontrolka – reaguje na kliknięcie.

Właściwości:

  • Text (Forms) / Content (WPF) – tekst wyświetlany na przycisku.
  • Enabled / IsEnabled – włącza lub wyłącza przycisk (np. szary, nieaktywny).
  • Visible / Visibility – pokazuje lub ukrywa przycisk.
  • BackColor / Background – kolor tła.
  • ForeColor / Foreground – kolor tekstu.
  • Font – styl i rozmiar czcionki.

Zdarzenie (Forms):

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

Po kliknięciu wykonywany jest kod w tej metodzie.


WPF i pojęcie Command

W WPF przycisk może korzystać nie tylko z eventu Click, ale też z Command – czyli polecenia.
Command to specjalna właściwość, która łączy przycisk z metodą w logice aplikacji (ViewModelu).
To pozwala oddzielić wygląd od działania – przycisk „wie”, co ma wykonać, ale nie zna kodu tej metody.

<Button Content="Zapisz" Command="{Binding ZapiszCommand}" />

W ViewModelu definiujesz:

public ICommand ZapiszCommand { get; }

public MainViewModel()
{
    ZapiszCommand = new Command(WykonajZapis);
}

private void WykonajZapis()
{
    Wynik = "Dane zapisane!";
}

Efekt: po kliknięciu przycisku metoda WykonajZapis() uruchamia się automatycznie.
Command to nowoczesny sposób obsługi zdarzeń – szczególnie przydatny w MAUI i WPF.


TextBox – pole tekstowe

Służy do wprowadzania tekstu przez użytkownika.

Właściwości:

  • Text – zawartość pola.
  • MaxLength – ogranicza liczbę znaków.
  • Multiline (Forms) – pozwala pisać w kilku liniach.
  • ReadOnly / IsReadOnly – tylko do odczytu.
  • PasswordChar (Forms) / PasswordBox (WPF) – ukrywa znaki hasła.
  • Font, ForeColor / Foreground – wygląd tekstu.

Zdarzenie (Forms):

private void txtImie_TextChanged(object sender, EventArgs e)
{
    lblDlugosc.Text = $"Długość: {txtImie.TextLength}";
}

WPF – wersja z Bindingiem:

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

Efekt: tekst w polu automatycznie aktualizuje właściwość Imie w modelu danych.


Label / TextBlock – wyświetlanie tekstu

Label (Forms) służy do prostych opisów i wyników.
TextBlock (WPF) działa podobnie, ale obsługuje lepsze formatowanie.

Właściwości:

  • Text (Forms) / Text (WPF) – wyświetlany tekst.
  • AutoSize (Forms) – dopasowuje rozmiar etykiety do tekstu.
  • ForeColor / Foreground – kolor czcionki.
  • Font, TextAlign, BackColor.

Przykład (Forms):

lblWynik.Text = "Witaj, " + txtImie.Text + "!";

WPF:

<TextBlock Text="{Binding Wynik}" FontSize="16" Foreground="Blue"/>

CheckBox – zaznaczenie opcji

Właściwości:

  • Checked / IsChecked – czy zaznaczony.
  • Text / Content – opis obok pola.

Zdarzenie:

private void chkZgoda_CheckedChanged(object sender, EventArgs e)
{
    btnDalej.Enabled = chkZgoda.Checked;
}

Efekt: przycisk włącza się tylko, gdy uczeń zaznaczy zgodę.


RadioButton – wybór jednej opcji

RadioButtony działają w grupie – można wybrać tylko jeden z nich.

Właściwości:

  • Checked / IsChecked.
  • Text / Content.

Forms:

string plec = rbKobieta.Checked ? "Kobieta" : "Mężczyzna";

WPF:

<StackPanel>
  <RadioButton Content="Mężczyzna" IsChecked="{Binding CzyMezczyzna}" />
  <RadioButton Content="Kobieta"   IsChecked="{Binding CzyKobieta}" />
</StackPanel>

ComboBox – lista rozwijana

Właściwości:

  • Items – elementy listy.
  • SelectedItem / SelectedIndex – wybrany element lub jego numer.
  • DropDownStyle (Forms) – czy użytkownik może wpisywać własny tekst.
  • IsEditable (WPF) – odpowiednik tej opcji.

Forms:

comboBox1.Items.AddRange(new[] { "Kot", "Pies", "Papuga" });
comboBox1.SelectedIndexChanged += (_, __) =>
{
    lblWybor.Text = comboBox1.SelectedItem?.ToString();
};

WPF:

<ComboBox ItemsSource="{Binding Zwierzeta}"
          SelectedItem="{Binding WybraneZwierzze}" />

Slider (TrackBar w Forms)

Służy do wybierania wartości liczbowych przez przesuwanie suwaka.

Właściwości:

  • Minimum, Maximum – zakres wartości.
  • Value – aktualna pozycja.
  • TickFrequency – co ile pojawia się kreska na suwaku.
  • IsSnapToTickEnabled (WPF) – zaokrągla do najbliższej kreski.

Zdarzenie:

private void trackBar1_Scroll(object sender, EventArgs e)
{
    panel1.BackColor = Color.FromArgb(trackBar1.Value, 0, 0);
}

WPF:

<Slider Minimum="0" Maximum="255"
        Value="{Binding R, Mode=TwoWay}"
        TickFrequency="10"
        IsSnapToTickEnabled="True" />

Efekt: suwak zmienia intensywność koloru czerwonego w panelu.


SearchBar (MAUI/WPF)

W WPF nie ma wbudowanego SearchBar, ale w MAUI i nowoczesnych UI to standardowa kontrolka.

Właściwości:

  • Text – wpisane zapytanie.
  • Placeholder – tekst podpowiedzi („Szukaj…”).

Zdarzenie (Forms):

private void txtSearch_TextChanged(object sender, EventArgs e)
{
    var fraza = txtSearch.Text.ToLower();
    var wyniki = lista.Where(x => x.Contains(fraza)).ToList();
    listBox1.DataSource = wyniki;
}

WPF / MAUI (binding):

<SearchBar Placeholder="Szukaj..."
           Text="{Binding Zapytanie, UpdateSourceTrigger=PropertyChanged}" />

ListBox / DataGrid – listy danych

ListBox – do prostych list,
DataGrid – do tabel i rekordów.

Właściwości:

  • Items / ItemsSource – dane.
  • SelectedItem – wybrany element.
  • SelectionMode – pojedynczy czy wielokrotny wybór.

Forms:

listBox1.Items.AddRange(new[] { "Python", "C#", "Java" });

WPF:

<DataGrid ItemsSource="{Binding Studenci}" AutoGenerateColumns="True"/>

ProgressBar – pasek postępu

Właściwości:

  • Minimum, Maximum, Value – zakres i aktualny postęp.
  • Style = Marquee (Forms) / IsIndeterminate (WPF) – animowany pasek, gdy nie znamy czasu trwania.

Forms:

private async void btnStart_Click(object sender, EventArgs e)
{
    for (int i = 0; i <= 100; i += 10)
    {
        progressBar1.Value = i;
        await Task.Delay(100);
    }
}

Timer – cykliczne działania

Forms:

timer1.Interval = 1000;
timer1.Tick += (_, __) => lblCzas.Text = DateTime.Now.ToString("HH:mm:ss");
timer1.Start();

WPF:

var zegar = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
zegar.Tick += (_, __) => Zegar = DateTime.Now.ToString("HH:mm:ss");
zegar.Start();

Otwieranie nowych okien i przekazywanie danych

Windows Forms

// Form1
private void btnOtworz_Click(object sender, EventArgs e)
{
    var imie = txtImie.Text;
    var okno = new Form2(imie);
    okno.Show();
}

// Form2
public Form2(string imie)
{
    InitializeComponent();
    lblImie.Text = imie;
}

WPF

var okno = new SzczegolyWindow
{
    DataContext = new SzczegolyViewModel { Imie = txtImie.Text }
};
okno.Show();

Lub w aplikacjach z nawigacją:

await Navigation.PushAsync(new SzczegolyPage(model));

Podsumowanie

  • Windows Forms – szybki sposób tworzenia aplikacji z prostym kodem zdarzeń.
  • WPF – nowoczesne podejście, które pozwala oddzielić UI od logiki.
  • Większość właściwości i zachowań jest wspólna – różni się tylko zapis i sposób reagowania.
  • Command i Binding to przyszłość — czystszy i łatwiejszy w testowaniu kod.

C