This article has been localized into Russian by the community.
Элемент CheckBox
CheckBox позволяет пользователю переключать элемент управления, выбирая между "on" и "off". Это переключение обычно ассоциируется с переменной логического типа в CodeBehind. Давайте сразу рассмотрим это на примере, если Вы не до конца уверены в том, как выглядит элемент CheckBox:
<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>
Как Вы можете наблюдать, CheckBox крайне прост в использовании. На втором CheckBox я использовал свойство IsChecked, определяющее текущий элемент нажатым по умолчанию, и, кроме одного этого свойства, для функционирования элемента никакие другие не нужны. Свойство IsChecked так же может быть использовано из CodeBehind, если Вы хотите проверить, отмечен текущий CheckBox или нет.
Специальный контент
Элемент CheckBox наследует класс ContentControl, следовательно может содержать внутри себя и отображать специальный контент. Если Вы просто между тегами CheckBox впишете текст, как на примере выше, WPF поместит внутрь элемент TextBlock и отобразит его, но это лишь упрощение процесса для Вас. Внутри можно использовать любой тип элемента управления, как Вы заметите из следующего примера:
<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>
Из разметки, представленной выше, заметьте, что Вы можете использовать любое содержимое внутри этого элемента. Для трех представленных CheckBox'ов я оформил текст по-разному, а для второго добавил изображение. Определяя элемент как содержание, вместо классического Text, мы получаем больше контроля и полезный "момент" заключается в том, что неважно, на какую часть элемента CheckBox Вы нажмете, он все равно сработает.
Свойство IsThreeState
CheckBox обычно соответствует логической переменной, следовательно, он имеет только два состояния: true или false (on/off). Однако, переменная этого типа может быть "nullable", позволяя ввести третий вариант (true, false или null) и CheckBox, в свою очередь, тоже может поддерживать этот третий вариант. Установив свойство IsThreeState как true, элемент может принимать третье состояние, называемое "неопределенным".
Обычно, такой механизм используется для CheckBox'а типа "Выбрать все", который может как устанавливать состояния дочерних CheckBox'ов, так и отображать их. Наш пример показывает, каким образом Вы можете создать список опций, которые могут быть выбраны/не выбраны вместе с общим элементом "Выбрать все" наверху:
<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;
}
}
}
Такой механизм можно использовать двояко: если Вы включаете либо выключаете трехпозиционный CheckBox, тогда все дочерние (представляющие определенный функционал в нашем примере) будут включены либо выключены. И в обратную сторону, включение/выключение дочерних CheckBox'ов влияет на состояние трехпозиционного. Если они все выбраны/не выбраны, то включается/выключается общий, в противном же случае он переходит в неопределенное состояние.
Все описанные варианты поведения представлены на скриншотах выше и достигаются с помощью подписки на события Checked и Unchecked элемента CheckBox. В реальном приложении Вы скорее всего использовали бы привязку данных для CheckBox, пример показывает лишь основы использования свойства IsThreeState для трехпозиционных CheckBox'ов.