This article has been localized into Polish by the community.
Kontrolka Slider
Kontrolka Slider ( suwak ) umożliwia użytkownikowi aplikacji wskazanie wartości liczbowej poprzez przeciągnięcie specjalnego wskaźnika usytuowanego wzdłuż linii poziomej lub pionowej. Można je spotkać w wielu interfejsach użytkownika. Jednak nadal może sprawić trochę trudności rozpoznanie tej kontrolki po samym opisie, więc oto bardzo podstawowy przykład:
<Window x:Class="WpfTutorialSamples.Misc_controls.SliderSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SliderSample" Height="100" Width="300">
<StackPanel VerticalAlignment="Center" Margin="10">
<Slider Maximum="100" />
</StackPanel>
</Window>
Przykład ten umożliwia użytkownikowi aplikacji wskazanie wartości od 0 do 100 przeciągając wskaźnik wzdłuż widocznej linii poziomej.
Znaczniki
W przykładzie tym przeciągnąłem wskaźnik poza środek lini, ale oczywiście trudno jest ocenić dokładną wartość jaką w ten sposób wskazałem. Jednym ze sposobów zaradzenia temu jest włączenie widoczności znaczników, które są małymi kreseczkami ukazanymi pod linią. Dzięki temu można znacznie lepiej ocenić wartość jaką się wskazuje. Oto przykład:
<Window x:Class="WpfTutorialSamples.Misc_controls.SliderSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SliderSample" Height="100" Width="300">
<StackPanel VerticalAlignment="Center" Margin="10">
<Slider Maximum="100" TickPlacement="BottomRight" TickFrequency="5" />
</StackPanel>
</Window>
Włączam widoczność znaczników nadając właściwości TickPlacement inną wartość niż None, która jest wartością domyślną. W moim przykładzie chcę, aby znaczniki były umieszczone poniżej linii więc ustawiłem BottomRight, ale możesz użyć TopLeft lub nawet Both jako możliwych wartości, aby to zmienić.
Zwróć także uwagę na moje użycie właściwości TickFrequency oznaczającej gęstość stawianych znaczników. Domyślnie jest równa 1, ale w naszym przykładzie, w którym zakres możliwych wartości wynosi od 0 do 100, oznaczałoby to umieszczenie 101 znaczników, które trzebaby zmieścić w ograniczonej przestrzeni. W takich przypadkach sensowne jest podniesienie TickFrequency do wartości, która sprawi, że będzie mniej zagęszczony.
Przyciąganie do znaczników
Jeśli spojrzysz na powyższy zrzut ekranu, zobaczysz że wskaźnik znajduje się między znacznikami. Ma to sens, ponieważ między każdym znacznikiem znajduje się pięć wartości, zgodnie z właściwością TickFrequency. Ponadto wartość kontrolki Slider ( suwak ) jest w rzeczywistości domyślnie liczbą rzeczywistą typu double. Oznacza to, że wartość suwaka może być ( i prawdopodobnie będzie ) niecałkowita. Możemy to zmienić za pomocą właściwości IsSnapToTickEnabled, jak w poniższym przykładzie:
<Window x:Class="WpfTutorialSamples.Misc_controls.SliderSnapToTickSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SliderSnapToTickSample" Height="100" Width="300">
<StackPanel VerticalAlignment="Center" Margin="10">
<Slider Maximum="100" TickPlacement="BottomRight" TickFrequency="10" IsSnapToTickEnabled="True" />
</StackPanel>
</Window>
Zwróć uwagę, że zmieniłem TickFrequency na 10, a następnie włączyłem właściwość IsSnapToTickEnabled. Zapewnia to, że wskaźnik można umieścić tylko bezpośrednio na wartości dowolnego znacznika, więc w tym przykładzie może to być tylko 0, 10, 20, 30, 40 i tak dalej.
Wartość suwaka
Do tej pory stosowaliśmy kontrolkę Slider koncentrując się tylko na ilustracji, ale oczywiście rzeczywistym celem jej użycia jest odczytanie jej bieżącej wartości i zastosowanie jej w konkretnym celu. Suwak ma ku temu właściwość Value, którą możesz oczywiście odczytać z poziomu kodu C#, a nawet do niej wiązać dane.
Typowym scenariuszem korzystania z kontrolki suwak jest połączenie jej z kontrolką TextBox, co pozwoli użytkownikowi zobaczyć aktualnie wskazywaną wartość, a także zmienić ją przez ręczne wprowadzenie liczby zamiast przeciągania wskaźnika suwaka. Standardowo należałoby zastosować zdarzenia zmiany zarówno w Slider, jak i w TextBox, a następnie odpowiednio aktualizować właściwości, ale proste wiązanie danych może to wszystko zrobić za nas:
<Window x:Class="WpfTutorialSamples.Misc_controls.SliderBoundValueSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SliderBoundValueSample" Height="100" Width="300">
<DockPanel VerticalAlignment="Center" Margin="10">
<TextBox Text="{Binding ElementName=slValue, Path=Value, UpdateSourceTrigger=PropertyChanged}" DockPanel.Dock="Right" TextAlignment="Right" Width="40" />
<Slider Maximum="255" TickPlacement="BottomRight" TickFrequency="5" IsSnapToTickEnabled="True" Name="slValue" />
</DockPanel>
</Window>
Teraz możesz zmienić wartość suwaka, używając wskaźnika lub ręcznie wpisując liczbę w TextBox, a zostanie to natychmiast odzwierciedlone w drugiej kontrolce. Jako dodatkowy bonus otrzymujemy również prostą walidację poprawności wpisywanej liczby, bez dodatkowej pracy. Gdybyśmy wprowadzili w TextBox wartość nie będącą liczbą, zostanie to natychmiast zauważone i zaznaczone czerwoną ramką wokół TextBox:
Reagowanie na zmianę wartości
Oczywiście wiązania danych są bardzo fajne i trafione w wielu przypadkach, jednak nadal możesz chcieć zareagować na zmianę wartości suwaka z poziomu kodu C# ( Code-Behind ). Na szczęście dla nas kontrolka Slider jest wyposażona w zdarzenie ValueChanged, które nam w tym pomoże. Aby to zilustrować, stworzyłem bardziej złożony przykład z trzema suwakami, w których zmieniamy wartości koloru czerwonego, zielonego i niebieskiego (RGB):
<Window x:Class="WpfTutorialSamples.Misc_controls.SliderValueChangedSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SliderValueChangedSample" Height="200" Width="300">
<StackPanel Margin="10" VerticalAlignment="Center">
<DockPanel VerticalAlignment="Center" Margin="10">
<Label DockPanel.Dock="Left" FontWeight="Bold">R:</Label>
<TextBox Text="{Binding ElementName=slColorR, Path=Value, UpdateSourceTrigger=PropertyChanged}" DockPanel.Dock="Right" TextAlignment="Right" Width="40" />
<Slider Maximum="255" TickPlacement="BottomRight" TickFrequency="5" IsSnapToTickEnabled="True" Name="slColorR" ValueChanged="ColorSlider_ValueChanged" />
</DockPanel>
<DockPanel VerticalAlignment="Center" Margin="10">
<Label DockPanel.Dock="Left" FontWeight="Bold">G:</Label>
<TextBox Text="{Binding ElementName=slColorG, Path=Value, UpdateSourceTrigger=PropertyChanged}" DockPanel.Dock="Right" TextAlignment="Right" Width="40" />
<Slider Maximum="255" TickPlacement="BottomRight" TickFrequency="5" IsSnapToTickEnabled="True" Name="slColorG" ValueChanged="ColorSlider_ValueChanged" />
</DockPanel>
<DockPanel VerticalAlignment="Center" Margin="10">
<Label DockPanel.Dock="Left" FontWeight="Bold">B:</Label>
<TextBox Text="{Binding ElementName=slColorB, Path=Value, UpdateSourceTrigger=PropertyChanged}" DockPanel.Dock="Right" TextAlignment="Right" Width="40" />
<Slider Maximum="255" TickPlacement="BottomRight" TickFrequency="5" IsSnapToTickEnabled="True" Name="slColorB" ValueChanged="ColorSlider_ValueChanged" />
</DockPanel>
</StackPanel>
</Window>
using System;
using System.Windows;
using System.Windows.Media;
namespace WpfTutorialSamples.Misc_controls
{
public partial class SliderValueChangedSample : Window
{
public SliderValueChangedSample()
{
InitializeComponent();
}
private void ColorSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
Color color = Color.FromRgb((byte)slColorR.Value, (byte)slColorG.Value, (byte)slColorB.Value);
this.Background = new SolidColorBrush(color);
}
}
}
W kodzie XAML mamy trzy panele DockPanel, w każdym z nich kontrolką Label, Slider i TextBox. Tak jak poprzednio, właściwość Text kontrolek TextBox została przy użyciu wiązania danych skojarzona z wartością swojego suwaka.
Każdy suwak obsługuje to samo zdarzenie ValueChanged, w którym to tworzymy nową instancję Color na podstawie aktualnie wskazywanych wartości przez suwaki, a następnie używamy tego koloru do utworzenia nowego SolidColorBrush dla właściwości Background okna aplikacji.
Podsumowując, jest to całkiem dobry przykład tego, do czego można użyć kontrolki Slider.