This article has been localized into Polish by the community.
Kontrolka CheckBox
Kontrolka CheckBox pozwala użytkownikowi na przełączanie pomiędzy wartościami włączono/wyłączono, co w kodzie za-widokiem jest reprezentowane za pomocą typu logicznego. Spójrzmy bezpośrednio na przykład, jeśli nie jesteś pewien jak CheckBox wygląda:
<Window x:Class="WpfTutorialSamples.Basic_controls.CheckBoxSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CheckBoxSample" Height="140" Width="250">
<StackPanel Margin="10">
<Label FontWeight="Bold">Application Options</Label>
<CheckBox>Enable feature ABC</CheckBox>
<CheckBox IsChecked="True">Enable feature XYZ</CheckBox>
<CheckBox>Enable feature WWW</CheckBox>
</StackPanel>
</Window>
Jak widzisz CheckBox jest bardzo prosty w użyciu. W drugim polu wyboru użyłem właściwości IsChecked, aby ustawić, że ten CheckBox jest domyślnie zaznaczony – jest to najważniejsza właściwość tej kontrolki. Wartość pola IsChecked jest również używana w kodzie za-widokiem, kiedy chcesz sprawdzić, czy dane pole wyboru zostało zaznaczone czy też nie.
Manipulowanie zawartością
Kontrolka CheckBox dziedziczy po klasie ContentControl co pozwala na dowolne modyfikowanie zawartości. Kiedy jako zawartość wprowadzisz sam tekst, jak zrobiłem w przykładzie powyżej, to WPF umieści go wewnątrz TextBlocka i wyświetli go – jednak jest to tylko skrót, aby uczynić rzeczy łatwiejszymi. Możesz użyć dowolnego typu kontrolki wewnątrz pola wyboru jak zrobiliśmy to poniżej:
<Window x:Class="WpfTutorialSamples.Basic_controls.CheckBoxSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CheckBoxSample" Height="140" Width="250">
<StackPanel Margin="10">
<Label FontWeight="Bold">Application Options</Label>
<CheckBox>
<TextBlock>
Enable feature <Run Foreground="Green" FontWeight="Bold">ABC</Run>
</TextBlock>
</CheckBox>
<CheckBox IsChecked="True">
<WrapPanel>
<TextBlock>
Enable feature <Run FontWeight="Bold">XYZ</Run>
</TextBlock>
<Image Source="/WpfTutorialSamples;component/Images/question.png" Width="16" Height="16" Margin="5,0" />
</WrapPanel>
</CheckBox>
<CheckBox>
<TextBlock>
Enable feature <Run Foreground="Blue" TextDecorations="Underline" FontWeight="Bold">WWW</Run>
</TextBlock>
</CheckBox>
</StackPanel>
</Window>
Jak widzisz z składni w przykładzie możesz zrobić praktycznie co tylko chcesz z zawartością tej kontrolki. W każdym z trzech CheckBoxów zrobiłem coś kompletnie innego z tekstem, a w środkowym nawet dodałem obrazek. Określając zawartość kontrolki bezpośrednio zamiast zwykłym tekstem dostajemy dużo większą kontrolę nad jej wyglądem, a fajną sprawą jest to, że nie ma znaczenia, na który jej element klikniemy, aby przełączyć jej wartość.
Właściwość IsThreeState
Jak wspomniano wcześniej, zazwyczaj wartość CheckBoxa odpowiada wartości logicznej, co znaczy, że może on mieć tylko dwa stany: prawda (true) lub fałsz (false). Jednak od kiedy typ logiczny może być pusty (nullable), czyli zawierać trzy wartości: prawda (true), fałsz (false) lub nic (null), to kontrolka pola wyboru również zaczęła wspierać ten trzeci przypadek. Poprzez ustawienie właściwości IsThreeState na „prawda” CheckBox zyskuje trzeci stan zwany nieokreślonym (indeterminate state).
Powszechnym zastosowaniem dla tej funkcjonalności jest pole „Zaznacz wszystko”, które potrafi kontrolować wartość wszystkich podrzędnych CheckBoxów oraz pokazać ich wspólną wartość. Nasz przykład pokazuje jak możesz utworzyć listę funkcjonalności, które mogą być przełączane między włącz a wyłącz wraz z CheckBoxem realizacyjnym zadanie "Zaznacz wszystkie":
<Window x:Class="WpfTutorialSamples.Basic_controls.CheckBoxThreeStateSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CheckBoxThreeStateSample" Height="170" Width="300">
<StackPanel Margin="10">
<Label FontWeight="Bold">Application Options</Label>
<StackPanel Margin="10,5">
<CheckBox IsThreeState="True" Name="cbAllFeatures" Checked="cbAllFeatures_CheckedChanged" Unchecked="cbAllFeatures_CheckedChanged">Enable all</CheckBox>
<StackPanel Margin="20,5">
<CheckBox Name="cbFeatureAbc" Checked="cbFeature_CheckedChanged" Unchecked="cbFeature_CheckedChanged">Enable feature ABC</CheckBox>
<CheckBox Name="cbFeatureXyz" IsChecked="True" Checked="cbFeature_CheckedChanged" Unchecked="cbFeature_CheckedChanged">Enable feature XYZ</CheckBox>
<CheckBox Name="cbFeatureWww" Checked="cbFeature_CheckedChanged" Unchecked="cbFeature_CheckedChanged">Enable feature WWW</CheckBox>
</StackPanel>
</StackPanel>
</StackPanel>
</Window>
using System;
using System.Windows;
namespace WpfTutorialSamples.Basic_controls
{
public partial class CheckBoxThreeStateSample : Window
{
public CheckBoxThreeStateSample()
{
InitializeComponent();
}
private void cbAllFeatures_CheckedChanged(object sender, RoutedEventArgs e)
{
bool newVal = (cbAllFeatures.IsChecked == true);
cbFeatureAbc.IsChecked = newVal;
cbFeatureXyz.IsChecked = newVal;
cbFeatureWww.IsChecked = newVal;
}
private void cbFeature_CheckedChanged(object sender, RoutedEventArgs e)
{
cbAllFeatures.IsChecked = null;
if((cbFeatureAbc.IsChecked == true) && (cbFeatureXyz.IsChecked == true) && (cbFeatureWww.IsChecked == true))
cbAllFeatures.IsChecked = true;
if((cbFeatureAbc.IsChecked == false) && (cbFeatureXyz.IsChecked == false) && (cbFeatureWww.IsChecked == false))
cbAllFeatures.IsChecked = false;
}
}
}
Ten przykład działa na dwa różne sposoby: Jeśli klikniesz „Zaznacz wszystkie” wtedy wszystkie podrzędne pola wyboru zostaną zaznaczone bądź odznaczone. Drugi przypadek występuje wtedy, gdy bezpośrednio zaznaczasz pola wyboru reprezentujące pojedyncze funkcje: wtedy jeśli wszystkie pola są zaznaczone lubo odznaczone, to pole „Zaznacz wszystkie” przyjmuje tę samą wartość, jeśli natomiast wartości są mieszane (część zaznaczona a część odznaczona) to pole to przyjmie wartość null reprezentowaną przez stan nieokreślony.
Funkcjonalność widoczna na powyższym zrzucie ekranu została osiągnięta poprzez subskrypcję (obsługę) zdarzeń Checked (zaznaczono) i Unchecked (odznaczono) kontrolki CheckBox. W prawdziwym świecie użyłbyś raczej łączenia wartość (bindowania) zamiast obsługi zdarzeń. Jednak ten przykład pokazuje tylko podstawy używania właściwości IsThreeState aby stworzyć przycisk "Zaznacz wszystkie".