Jak pozwolić użytkownikowi wybrać wartość liczbową z przedziału od 0 do 255 (np. jasność ekranu, głośność muzyki lub składową koloru RGB), mając 100% pewności, że nie wpisze tam ujemnej liczby, liter ani wartości 9999?
Odpowiedzią jest kontrolka Slider (suwak). To jeden z absolutnych ulubieńców komisji egzaminacyjnej CKE - pojawia się w zadaniach z wzornikiem kolorów RGB, generatorem haseł czy zmianą rozmiaru czcionki. Zobaczmy, jak go zaprogramować bez potknięć!
1. Anatomia kontrolki Slider: Koniec z ułamkami!
Gdy wrzucisz domyślny Slider do okna i przesuniesz go myszką, jego właściwość Value zwróci liczbę zmiennoprzecinkową typu double, np. 47.3829104. W większości zadań egzaminacyjnych potrzebujemy jednak czystych liczb całkowitych.
Aby zmusić suwak do skakania wyłącznie po pełnych liczbach, w XAML ustawiamy zestaw czterech właściwości:
| Właściwość XAML | Do czego służy? | Przykład dla RGB |
Minimum |
Wartość minimalna (lewy skraj suwaka). | Minimum="0" |
Maximum |
Wartość maksymalna (prawy skraj suwaka). | Maximum="255" |
Value |
Początkowa pozycja suwaka. | Value="255" |
TickFrequency |
Co ile jednostek rozmieszczone są podziałki (kroki). | TickFrequency="1" |
IsSnapToTickEnabled |
Kluczowe! Przyciąga suwak dokładnie do podziałek (eliminuje ułamki!). | IsSnapToTickEnabled="True" |
<Slider x:Name="slCzerwony"
Minimum="0"
Maximum="255"
Value="128"
TickFrequency="1"
IsSnapToTickEnabled="True"
ValueChanged="SuwakRGB_ValueChanged" />

2. ProgressBar: Wizualny brat suwaka
Kontrolka ProgressBar (pasek postępu) posiada dokładnie te same właściwości zakresowe co suwak (Minimum, Maximum, Value), ale jest tylko do odczytu - użytkownik nie może jej przesuwać myszką.
<ProgressBar x:Name="pbPostep" Minimum="0" Maximum="100" Value="65" Height="20" />

Świetnie sprawdza się do wizualizacji zapełnienia dysku, siły hasła lub postępu ładowania.
3. Zdarzenie ValueChanged i mikser kolorów RGB w C#
Aby aplikacja reagowała płynnie podczas przeciągania suwaka, podpinamy zdarzenie ValueChanged.
W zadaniach egzaminacyjnych bardzo często musimy na podstawie trzech suwaków (Red, Green, Blue) pokolorować tło wybranego elementu (np. Rectangle, Border lub StackPanel). W WPF do nadania koloru używamy pędzla SolidColorBrush oraz struktury Color.FromRgb:
Kod C#
using System.Windows.Media; // Wymagane dla SolidColorBrush i Color!
private void SuwakRGB_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
// 1. STRAŻNIK: Chroni przed błędem podczas uruchamiania okna!
if (slR == null || slG == null || slB == null || rectWzornik == null)
return;
// 2. Pobieramy wartości z suwaków i rzutujemy z double na byte (zakres 0-255)
byte r = (byte)slR.Value;
byte g = (byte)slG.Value;
byte b = (byte)slB.Value;
// 3. Aktualizujemy etykiety tekstowe obok suwaków
lblR.Text = r.ToString();
lblG.Text = g.ToString();
lblB.Text = b.ToString();
// 4. Malujemy tło kontrolki nowym kolorem RGB
rectWzornik.Background = new SolidColorBrush(Color.FromRgb(r, g, b));
}
🧠 Dlaczego na początku metody potrzebny jest „Strażnik” (
if (slR == null...) return)?
Gdy okno startuje i wykonuje metodęInitializeComponent(), WPF czyta Twój plik XAML linijka po linijce. Kiedy natrafi na pierwszy suwakslRz ustawionymValue="255", natychmiast odpala zdarzenieValueChanged- zanim jeszcze zdąży utworzyć suwakislGislBznajdujące się niżej w kodzie! Linijka sprawdzającanullchroni program przed wyłożeniem się przy starcie.
4. Zobaczmy to w akcji: Kompletny wzornik RGB
Oto gotowy układ XAML dla klasycznego zadania z mieszaniem barw:
XAML
<StackPanel Margin="20">
<!-- Duży podgląd mieszanego koloru -->
<Border x:Name="rectWzornik" Height="100" Background="Black" BorderBrush="Gray" BorderThickness="1" Margin="0,0,0,20" />
<!-- Suwak R (Red) -->
<DockPanel Margin="0,0,0,10">
<TextBlock Text="R:" Width="25" FontWeight="Bold" />
<TextBlock x:Name="lblR" Text="0" Width="35" DockPanel.Dock="Right" TextAlignment="Right" />
<Slider x:Name="slR" Minimum="0" Maximum="255" TickFrequency="1" IsSnapToTickEnabled="True" ValueChanged="SuwakRGB_ValueChanged" />
</DockPanel>
<!-- Suwak G (Green) -->
<DockPanel Margin="0,0,0,10">
<TextBlock Text="G:" Width="25" FontWeight="Bold" />
<TextBlock x:Name="lblG" Text="0" Width="35" DockPanel.Dock="Right" TextAlignment="Right" />
<Slider x:Name="slG" Minimum="0" Maximum="255" TickFrequency="1" IsSnapToTickEnabled="True" ValueChanged="SuwakRGB_ValueChanged" />
</DockPanel>
<!-- Suwak B (Blue) -->
<DockPanel Margin="0,0,0,10">
<TextBlock Text="B:" Width="25" FontWeight="Bold" />
<TextBlock x:Name="lblB" Text="0" Width="35" DockPanel.Dock="Right" TextAlignment="Right" />
<Slider x:Name="slB" Minimum="0" Maximum="255" TickFrequency="1" IsSnapToTickEnabled="True" ValueChanged="SuwakRGB_ValueChanged" />
</DockPanel>
</StackPanel>
