GroupBox w WPF – ramka porządkująca interfejs

Nauczysz się używać kontrolki GroupBox do logicznego grupowania elementów w oknie aplikacji. To podstawa tworzenia przejrzystych formularzy!

GroupBox XAML RadioButton formularze UI/UX
01

Co to jest GroupBox?

GroupBox to kontrolka WPF, która tworzy ramkę z nagłówkiem wokół grupy powiązanych elementów. Pomaga wizualnie i logicznie uporządkować interfejs użytkownika.

Analogia: Pudełko z etykietą

Wyobraź sobie pudełko na biurku z naklejką „Przybory do pisania”. W środku masz:

  • Długopisy
  • Ołówki
  • Markery

GroupBox działa tak samo – tworzy „pudełko” z etykietą (nagłówkiem), w którym grupujesz powiązane kontrolki.

GroupBox
Header = „Dane osobowe”
─────────────────
[ TextBox: Imię ]
[ TextBox: Nazwisko ]
[ TextBox: Email ]
GroupBox
Header = „Płeć”
─────────────────
○ Kobieta
○ Mężczyzna
○ Inna

↑ Dwa GroupBox-y porządkują formularz

Po co używać GroupBox?

ZaletaOpis
OrganizacjaGrupuje powiązane elementy (np. dane adresowe, opcje płatności)
CzytelnośćUżytkownik od razu widzi, co do czego należy
Logika RadioButtonRadioButtony w jednym GroupBox działają jako jedna grupa
EstetykaRamka z nagłówkiem wygląda profesjonalnie
02

Podstawowa składnia XAML

GroupBox ma prostą strukturę: nagłówek (Header) i zawartość (Content).

xaml/PodstawowyGroupBox.xaml XAML
<GroupBox Header="Dane użytkownika">
    <!-- Tutaj umieszczamy kontrolki -->
    <StackPanel>
        <TextBox Text="Jan Kowalski"/>
        <TextBox Text="jan@email.pl"/>
    </StackPanel>
</GroupBox>
Uwaga: Tylko JEDEN element bezpośrednio w GroupBox!

GroupBox może zawierać tylko jeden element potomny (Content). Jeśli chcesz umieścić więcej kontrolek, musisz je „opakować” w kontener:

  • StackPanel – układa elementy jeden pod drugim
  • Grid – siatka wierszy i kolumn
  • WrapPanel – zawija elementy do nowej linii

Struktura GroupBox

GroupBox
Ramka z nagłówkiem
Header
Tekst nagłówka
„Dane osobowe”
+
Content
Jeden kontener
(StackPanel/Grid)
Kontrolki
TextBox, Button,
CheckBox…

Przykład minimalny

xaml/Minimalny.xaml XAML
<Window x:Class="MojaAplikacja.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="GroupBox Demo" Height="300" Width="400">
    
    <StackPanel Margin="10">
        
        <GroupBox Header="Informacje podstawowe" Margin="0,0,0,10">
            <StackPanel Margin="10">
                <Label Content="Imię:"/>
                <TextBox Name="txtImie"/>
                <Label Content="Nazwisko:"/>
                <TextBox Name="txtNazwisko"/>
            </StackPanel>
        </GroupBox>
        
        <Button Content="Zapisz" Width="100"/>
        
    </StackPanel>
</Window>
03

Najważniejsze właściwości

WłaściwośćTypOpisPrzykład
HeaderobjectTekst lub kontrolka w nagłówkuHeader="Opcje"
ContentobjectZawartość GroupBoxStackPanel z kontrolkami
BorderBrushBrushKolor ramkiBorderBrush="Blue"
BorderThicknessThicknessGrubość ramkiBorderThickness="2"
PaddingThicknessWewnętrzny marginesPadding="10"
MarginThicknessZewnętrzny marginesMargin="5"
IsEnabledboolCzy aktywnyIsEnabled="False"
VisibilityVisibilityWidocznośćVisibility="Collapsed"

Przykład z różnymi właściwościami

xaml/Wlasciwosci.xaml XAML
<!-- Prosty GroupBox -->
<GroupBox Header="Podstawowy">
    <TextBlock Text="Zawartość"/>
</GroupBox>

<!-- Z kolorową ramką -->
<GroupBox Header="Ważne informacje"
          BorderBrush="Red"
          BorderThickness="2">
    <TextBlock Text="To jest ważne!"/>
</GroupBox>

<!-- Z większym paddingiem -->
<GroupBox Header="Przestronny"
          Padding="20">
    <TextBlock Text="Dużo miejsca wokół"/>
</GroupBox>

<!-- Wyłączony (wyszarzony) -->
<GroupBox Header="Niedostępne opcje"
          IsEnabled="False">
    <CheckBox Content="Ta opcja jest wyłączona"/>
</GroupBox>
Header może być czymś więcej niż tekstem!

Właściwość Header przyjmuje dowolny obiekt. Możesz tam umieścić np. StackPanel z ikoną i tekstem:

xaml/HeaderZIkona.xaml XAML
<GroupBox>
    <GroupBox.Header>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="⚙️" FontSize="16" Margin="0,0,5,0"/>
            <TextBlock Text="Ustawienia" FontWeight="Bold"/>
        </StackPanel>
    </GroupBox.Header>
    
    <StackPanel>
        <CheckBox Content="Opcja 1"/>
        <CheckBox Content="Opcja 2"/>
    </StackPanel>
</GroupBox>
04

Grupowanie RadioButton – najważniejsze zastosowanie

GroupBox jest idealny do grupowania RadioButton. Wszystkie RadioButtony w jednym GroupBox działają jako jedna grupa – można wybrać tylko jedną opcję.

Jak działa RadioButton w GroupBox?

RadioButtony automatycznie „wiedzą”, że są w jednej grupie, gdy mają wspólnego rodzica (np. ten sam StackPanel wewnątrz GroupBox). Wybranie jednego RadioButton automatycznie odznacza pozostałe.

xaml/RadioButtonGrupa.xaml XAML
<StackPanel Margin="10">
    
    <!-- GRUPA 1: Rozmiar -->
    <GroupBox Header="Wybierz rozmiar" Margin="0,0,0,10">
        <StackPanel>
            <RadioButton Content="Mały" Name="rbMaly"/>
            <RadioButton Content="Średni" Name="rbSredni" IsChecked="True"/>
            <RadioButton Content="Duży" Name="rbDuzy"/>
        </StackPanel>
    </GroupBox>
    
    <!-- GRUPA 2: Kolor (niezależna od grupy rozmiaru!) -->
    <GroupBox Header="Wybierz kolor" Margin="0,0,0,10">
        <StackPanel>
            <RadioButton Content="Czerwony" Name="rbCzerwony"/>
            <RadioButton Content="Zielony" Name="rbZielony"/>
            <RadioButton Content="Niebieski" Name="rbNiebieski" IsChecked="True"/>
        </StackPanel>
    </GroupBox>
    
    <Button Content="Zatwierdź wybór" Click="Button_Click"/>
    
</StackPanel>
GroupBox „Rozmiar”
○ Mały
● Średni ← wybrano
○ Duży
GroupBox „Kolor”
○ Czerwony
○ Zielony
● Niebieski ← wybrano

↑ Dwie niezależne grupy – możesz wybrać Średni rozmiar I Niebieski kolor

Obsługa w kodzie C#

cs/MainWindow.xaml.cs C#
private void Button_Click(object sender, RoutedEventArgs e)
{
    // Sprawdzamy rozmiar
    string rozmiar = "";
    if (rbMaly.IsChecked == true) rozmiar = "Mały";
    else if (rbSredni.IsChecked == true) rozmiar = "Średni";
    else if (rbDuzy.IsChecked == true) rozmiar = "Duży";
    
    // Sprawdzamy kolor
    string kolor = "";
    if (rbCzerwony.IsChecked == true) kolor = "Czerwony";
    else if (rbZielony.IsChecked == true) kolor = "Zielony";
    else if (rbNiebieski.IsChecked == true) kolor = "Niebieski";
    
    MessageBox.Show($"Wybrałeś: {rozmiar}, {kolor}");
}
Dlaczego == true a nie samo IsChecked?

IsChecked jest typu bool? (nullable bool) – może być true, false lub null. Dlatego porównujemy explicite z true.

05

Grupowanie CheckBox

CheckBox-y też często grupujemy w GroupBox – dla czytelności. W przeciwieństwie do RadioButton, można zaznaczyć wiele CheckBox-ów naraz.

xaml/CheckBoxGrupa.xaml XAML
<GroupBox Header="Wybierz dodatki do pizzy" Margin="10">
    <StackPanel>
        <CheckBox Content="Ser" Name="chkSer" IsChecked="True"/>
        <CheckBox Content="Szynka" Name="chkSzynka"/>
        <CheckBox Content="Pieczarki" Name="chkPieczarki"/>
        <CheckBox Content="Oliwki" Name="chkOliwki"/>
        <CheckBox Content="Pepperoni" Name="chkPepperoni"/>
    </StackPanel>
</GroupBox>

<Button Content="Zamów" Click="Zamow_Click"/>
cs/MainWindow.xaml.cs C#
private void Zamow_Click(object sender, RoutedEventArgs e)
{
    List<string> dodatki = new List<string>();
    
    if (chkSer.IsChecked == true) dodatki.Add("Ser");
    if (chkSzynka.IsChecked == true) dodatki.Add("Szynka");
    if (chkPieczarki.IsChecked == true) dodatki.Add("Pieczarki");
    if (chkOliwki.IsChecked == true) dodatki.Add("Oliwki");
    if (chkPepperoni.IsChecked == true) dodatki.Add("Pepperoni");
    
    string lista = string.Join(", ", dodatki);
    MessageBox.Show($"Twoja pizza z: {lista}");
}

RadioButton

Można wybrać tylko jedną opcję z grupy

  • ○ Opcja A
  • ● Opcja B ← wybrana
  • ○ Opcja C

Użyj gdy: rozmiar, płeć, metoda płatności

CheckBox

Można wybrać dowolną liczbę opcji

  • ☑ Opcja A ← wybrana
  • ☐ Opcja B
  • ☑ Opcja C ← wybrana

Użyj gdy: dodatki, zainteresowania, zgody

06

Zagnieżdżanie kontrolek w GroupBox

W GroupBox możesz umieścić dowolne kontrolki – TextBox, ComboBox, DatePicker, a nawet inne GroupBox-y!

Formularz z różnymi kontrolkami

xaml/FormularzKompletny.xaml XAML
<StackPanel Margin="10">
    
    <!-- DANE OSOBOWE -->
    <GroupBox Header="Dane osobowe" Margin="0,0,0,10">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
            </Grid.RowDefinitions>
            
            <Label Content="Imię:" Grid.Row="0"/>
            <TextBox Name="txtImie" Grid.Row="0" Grid.Column="1"/>
            
            <Label Content="Nazwisko:" Grid.Row="1"/>
            <TextBox Name="txtNazwisko" Grid.Row="1" Grid.Column="1"/>
            
            <Label Content="Data ur.:" Grid.Row="2"/>
            <DatePicker Name="dpDataUrodzenia" Grid.Row="2" Grid.Column="1"/>
        </Grid>
    </GroupBox>
    
    <!-- ADRES -->
    <GroupBox Header="Adres zamieszkania" Margin="0,0,0,10">
        <StackPanel>
            <TextBox Name="txtUlica" Margin="0,5"/>
            <StackPanel Orientation="Horizontal">
                <TextBox Name="txtKodPocztowy" Width="80" Margin="0,0,10,0"/>
                <TextBox Name="txtMiasto" Width="150"/>
            </StackPanel>
        </StackPanel>
    </GroupBox>
    
    <!-- PREFERENCJE -->
    <GroupBox Header="Preferencje">
        <StackPanel>
            <CheckBox Content="Newsletter"/>
            <CheckBox Content="Powiadomienia SMS"/>
            <ComboBox Margin="0,10,0,0">
                <ComboBoxItem Content="Polski" IsSelected="True"/>
                <ComboBoxItem Content="English"/>
                <ComboBoxItem Content="Deutsch"/>
            </ComboBox>
        </StackPanel>
    </GroupBox>
    
</StackPanel>

Zagnieżdżone GroupBox-y (GroupBox w GroupBox)

xaml/Zagniezdzone.xaml XAML
<GroupBox Header="Ustawienia programu" Padding="10">
    <StackPanel>
        
        <!-- Zagnieżdżony GroupBox 1 -->
        <GroupBox Header="Wygląd" Margin="0,0,0,10">
            <StackPanel>
                <RadioButton Content="Jasny motyw"/>
                <RadioButton Content="Ciemny motyw" IsChecked="True"/>
            </StackPanel>
        </GroupBox>
        
        <!-- Zagnieżdżony GroupBox 2 -->
        <GroupBox Header="Dźwięk">
            <StackPanel>
                <CheckBox Content="Włącz dźwięki" IsChecked="True"/>
                <Slider Minimum="0" Maximum="100" Value="75"/>
            </StackPanel>
        </GroupBox>
        
    </StackPanel>
</GroupBox>
07

Stylowanie GroupBox

Możesz dostosować wygląd GroupBox-a za pomocą właściwości lub stylów.

Podstawowe stylowanie

xaml/Stylowanie.xaml XAML
<!-- Kolorowa ramka -->
<GroupBox Header="Ważne"
          BorderBrush="#E74C3C"
          BorderThickness="2"
          Padding="15">
    <TextBlock Text="Uwaga!"/>
</GroupBox>

<!-- Z tłem -->
<GroupBox Header="Podświetlony"
          Background="#F0F8FF"
          Padding="10">
    <TextBlock Text="Jasne tło"/>
</GroupBox>

<!-- Stylizowany nagłówek -->
<GroupBox Padding="10">
    <GroupBox.Header>
        <TextBlock Text="★ Premium" 
                   FontWeight="Bold" 
                   Foreground="Gold"
                   FontSize="14"/>
    </GroupBox.Header>
    <TextBlock Text="Funkcje premium"/>
</GroupBox>

Styl w zasobach (reużywalny)

xaml/StylZasoby.xaml XAML
<Window.Resources>
    <!-- Definicja stylu -->
    <Style x:Key="StylWazny" TargetType="GroupBox">
        <Setter Property="BorderBrush" Value="#3498DB"/>
        <Setter Property="BorderThickness" Value="2"/>
        <Setter Property="Padding" Value="10"/>
        <Setter Property="Margin" Value="5"/>
        <Setter Property="FontWeight" Value="SemiBold"/>
    </Style>
</Window.Resources>

<StackPanel>
    <!-- Użycie stylu -->
    <GroupBox Header="Pierwszy" Style="{StaticResource StylWazny}">
        <TextBlock Text="Zawartość"/>
    </GroupBox>
    
    <GroupBox Header="Drugi" Style="{StaticResource StylWazny}">
        <TextBlock Text="Inna zawartość"/>
    </GroupBox>
</StackPanel>
08

Obsługa GroupBox w kodzie C#

Możesz dynamicznie zmieniać właściwości GroupBox z poziomu kodu C#.

Zmiana właściwości

xaml/GroupBoxDynamiczny.xaml XAML
<GroupBox Name="grpOpcje" Header="Opcje">
    <StackPanel>
        <CheckBox Content="Opcja 1"/>
        <CheckBox Content="Opcja 2"/>
    </StackPanel>
</GroupBox>

<Button Content="Włącz/Wyłącz" Click="Toggle_Click"/>
<Button Content="Zmień nagłówek" Click="ZmienHeader_Click"/>
<Button Content="Pokaż/Ukryj" Click="Visibility_Click"/>
cs/MainWindow.xaml.cs C#
// Włącz/Wyłącz GroupBox (i wszystkie kontrolki wewnątrz)
private void Toggle_Click(object sender, RoutedEventArgs e)
{
    grpOpcje.IsEnabled = !grpOpcje.IsEnabled;
}

// Zmień tekst nagłówka
private void ZmienHeader_Click(object sender, RoutedEventArgs e)
{
    grpOpcje.Header = "Nowy nagłówek";
}

// Pokaż/Ukryj GroupBox
private void Visibility_Click(object sender, RoutedEventArgs e)
{
    if (grpOpcje.Visibility == Visibility.Visible)
        grpOpcje.Visibility = Visibility.Collapsed;
    else
        grpOpcje.Visibility = Visibility.Visible;
}

Dynamiczne tworzenie GroupBox

cs/DynamiczneGroupBox.cs C#
private void UtworzGroupBox()
{
    // Tworzenie GroupBox
    GroupBox nowyGroupBox = new GroupBox();
    nowyGroupBox.Header = "Utworzony dynamicznie";
    nowyGroupBox.Margin = new Thickness(10);
    
    // Tworzenie zawartości
    StackPanel panel = new StackPanel();
    panel.Children.Add(new CheckBox { Content = "Opcja A" });
    panel.Children.Add(new CheckBox { Content = "Opcja B" });
    panel.Children.Add(new CheckBox { Content = "Opcja C" });
    
    // Przypisanie zawartości
    nowyGroupBox.Content = panel;
    
    // Dodanie do okna (zakładając że mamy StackPanel o nazwie "mainPanel")
    mainPanel.Children.Add(nowyGroupBox);
}
09

Praktyczne przykłady

Przykład 1: Formularz rejestracji

xaml/FormularzRejestracji.xaml XAML
<Window Title="Rejestracja" Height="500" Width="400">
    <StackPanel Margin="15">
        
        <!-- DANE KONTA -->
        <GroupBox Header="Dane konta" Margin="0,0,0,10">
            <StackPanel Margin="10">
                <Label Content="Email:"/>
                <TextBox Name="txtEmail"/>
                <Label Content="Hasło:" Margin="0,10,0,0"/>
                <PasswordBox Name="txtHaslo"/>
                <Label Content="Powtórz hasło:" Margin="0,10,0,0"/>
                <PasswordBox Name="txtHaslo2"/>
            </StackPanel>
        </GroupBox>
        
        <!-- TYP KONTA -->
        <GroupBox Header="Typ konta" Margin="0,0,0,10">
            <StackPanel Margin="10">
                <RadioButton Content="Konto prywatne" IsChecked="True"/>
                <RadioButton Content="Konto firmowe"/>
                <RadioButton Content="Konto studenckie"/>
            </StackPanel>
        </GroupBox>
        
        <!-- ZGODY -->
        <GroupBox Header="Zgody i regulamin" Margin="0,0,0,10">
            <StackPanel Margin="10">
                <CheckBox Content="Akceptuję regulamin" Name="chkRegulamin"/>
                <CheckBox Content="Zgoda na newsletter"/>
                <CheckBox Content="Zgoda na marketing"/>
            </StackPanel>
        </GroupBox>
        
        <Button Content="Zarejestruj się" Height="35" Click="Rejestruj_Click"/>
        
    </StackPanel>
</Window>

Przykład 2: Konfiguracja zamówienia

xaml/Zamowienie.xaml XAML
<Grid Margin="10">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    
    <!-- Lewa kolumna -->
    <StackPanel Grid.Column="0" Margin="0,0,5,0">
        
        <GroupBox Header="Rozmiar pizzy" Margin="0,0,0,10">
            <StackPanel Margin="10">
                <RadioButton Content="Mała (25cm) - 20 zł"/>
                <RadioButton Content="Średnia (32cm) - 28 zł" IsChecked="True"/>
                <RadioButton Content="Duża (45cm) - 38 zł"/>
            </StackPanel>
        </GroupBox>
        
        <GroupBox Header="Rodzaj ciasta">
            <StackPanel Margin="10">
                <RadioButton Content="Cienkie" IsChecked="True"/>
                <RadioButton Content="Grube"/>
                <RadioButton Content="Z serem w brzegach (+5 zł)"/>
            </StackPanel>
        </GroupBox>
        
    </StackPanel>
    
    <!-- Prawa kolumna -->
    <GroupBox Header="Dodatki (+3 zł każdy)" Grid.Column="1" Margin="5,0,0,0">
        <StackPanel Margin="10">
            <CheckBox Content="Podwójny ser"/>
            <CheckBox Content="Szynka"/>
            <CheckBox Content="Pieczarki"/>
            <CheckBox Content="Oliwki"/>
            <CheckBox Content="Papryka"/>
            <CheckBox Content="Kukurydza"/>
            <CheckBox Content="Jalapeño"/>
        </StackPanel>
    </GroupBox>
    
</Grid>
10

Częste błędy

❌ Błąd 1: Wiele elementów bezpośrednio w GroupBox

❌ Źle

<GroupBox Header="Test">
    <TextBox/>
    <TextBox/>  <!-- BŁĄD! -->
</GroupBox>

GroupBox może mieć tylko jeden element potomny!

✅ Dobrze

<GroupBox Header="Test">
    <StackPanel>
        <TextBox/>
        <TextBox/>
    </StackPanel>
</GroupBox>

Opakuj w kontener (StackPanel, Grid…)

❌ Błąd 2: RadioButtony w różnych kontenerach

❌ Źle

<GroupBox Header="Wybór">
  <Grid>
    <StackPanel>
      <RadioButton Content="A"/>
    </StackPanel>
    <StackPanel>
      <RadioButton Content="B"/>
    </StackPanel>
  </Grid>
</GroupBox>

RadioButtony w różnych StackPanel-ach to różne grupy!

✅ Dobrze

<GroupBox Header="Wybór">
    <StackPanel>
      <RadioButton Content="A"/>
      <RadioButton Content="B"/>
    </StackPanel>
</GroupBox>

Wspólny kontener = jedna grupa

❌ Błąd 3: Brak Name dla kontrolek

❌ Źle

<RadioButton Content="Tak"/>
<RadioButton Content="Nie"/>

Jak sprawdzisz w C#, która opcja jest wybrana?

✅ Dobrze

<RadioButton Name="rbTak" Content="Tak"/>
<RadioButton Name="rbNie" Content="Nie"/>

Teraz możesz użyć: rbTak.IsChecked

❌ Błąd 4: Zapominanie o IsChecked == true

❌ Źle

if (rbTak.IsChecked)  // Błąd!

IsChecked to bool?, nie bool

✅ Dobrze

if (rbTak.IsChecked == true)

Porównaj explicite z true

11

Podsumowanie

Kluczowe informacje o GroupBox
  • GroupBox = ramka z nagłówkiem do grupowania kontrolek
  • Header = tekst (lub dowolna kontrolka) w nagłówku
  • Content = może być tylko JEDEN element (użyj StackPanel/Grid)
  • RadioButton w jednym GroupBox = jedna grupa (tylko 1 wybór)
  • CheckBox w GroupBox = dla czytelności (wiele wyborów)
  • Można zagnieżdżać GroupBox w GroupBox
  • Można stylować – BorderBrush, Padding, Background

Tabela szybkiego przypomnienia

Co chcesz zrobić?Jak to zrobić?
Utworzyć ramkę z tytułem<GroupBox Header="Tytuł">
Dodać wiele kontrolekOpakuj w <StackPanel>
Jedna opcja z wieluRadioButton w GroupBox
Wiele opcji narazCheckBox w GroupBox
Zmienić kolor ramkiBorderBrush="Red"
Wyłączyć sekcjęIsEnabled="False"
Ukryć sekcjęVisibility="Collapsed"
Zadania

Zadania praktyczne

📝 Zadanie 1: Formularz ankiety

Utwórz formularz ankiety z trzema GroupBox-ami:

  • Dane respondenta: imię (TextBox), wiek (ComboBox: 18-25, 26-35, 36-50, 50+)
  • Ocena produktu: RadioButtony (1-5 gwiazdek)
  • Co Ci się podobało: CheckBoxy (Cena, Jakość, Design, Obsługa klienta)

Dodaj przycisk „Wyślij” z obsługą Click, która wyświetli podsumowanie w MessageBox.

💡 Podpowiedź: Dla ComboBox użyj SelectedItem lub SelectedIndex

📝 Zadanie 2: Konfigurator komputera

Utwórz aplikację konfiguratora PC z GroupBox-ami:

  • Procesor: RadioButtony (Intel i5, Intel i7, AMD Ryzen 5, AMD Ryzen 7)
  • RAM: RadioButtony (8GB, 16GB, 32GB, 64GB)
  • Dysk: RadioButtony (256GB SSD, 512GB SSD, 1TB SSD, 1TB HDD)
  • Dodatkowe opcje: CheckBoxy (Karta graficzna, WiFi 6, Bluetooth)

Przycisk „Podsumuj konfigurację” ma pokazać wybrane komponenty.

💡 Podpowiedź: Możesz ułożyć GroupBox-y w Grid z 2 kolumnami

📝 Zadanie 3: Ustawienia aplikacji

Stwórz okno ustawień z zagnieżdżonymi GroupBox-ami:

  • Główny GroupBox „Ustawienia” zawiera:
    • GroupBox „Wygląd” – RadioButton: Jasny/Ciemny motyw
    • GroupBox „Język” – ComboBox z językami
    • GroupBox „Powiadomienia” – CheckBoxy: Email, SMS, Push

Dodaj przyciski „Zapisz” i „Anuluj”.

💡 Podpowiedź: Użyj Padding w głównym GroupBox, żeby było miejsce na zagnieżdżone

⭐ Zadanie 4: Dynamiczne włączanie sekcji

Utwórz formularz zamówienia gdzie:

  • CheckBox „Dostawa pod adres” – gdy zaznaczony, włącza GroupBox z polami adresu
  • CheckBox „Faktura VAT” – gdy zaznaczony, włącza GroupBox z danymi firmy

Użyj zdarzenia Checked i Unchecked CheckBox-a do zmiany IsEnabled GroupBox-ów.

💡 Podpowiedź: grpAdres.IsEnabled = chkDostawa.IsChecked == true;

⭐⭐ Zadanie 5: Kalkulator ceny

Rozbuduj konfigurator pizzy z przykładu:

  • Dodaj ceny do każdej opcji
  • Na bieżąco obliczaj i wyświetlaj sumę w TextBlock
  • Użyj zdarzeń Checked RadioButton i CheckBox

Suma powinna się aktualizować przy każdej zmianie wyboru.

💡 Podpowiedź: Utwórz metodę ObliczCene() wywoływaną przez wszystkie zdarzenia Checked