-
基础控件:

CheckBox 控件

CheckBox 控件允许用户启用或禁用一个选项,这通常在逻辑代码中对应一个布尔值。如果你不熟悉 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 属性来让它默认就被选中。除此之外,使用 CheckBox 不需要其他的属性。如果你想检查一个 CheckBox 是否被选中,也应在逻辑代码中检查 IsChecked 属性。

自定义内容

CheckBox 控件继承自 ContentControl 类,这意味着它可以接受自定义内容并把它显示在旁边。如果你像我在上面的例子中一样,指定了一些文本,WPF 就会把它放入一个 TextBlock 控件并显示出来。这比手工创建 TextBlock 控件要方便。在 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>
			<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 里每一个的文本格式都不一样,我甚至在第二个里放了一个 Image 控件。如果我们用控件而非文本作为 CheckBox 的内容,我们就能随意控制样式。更酷的是,无论你点击内容的哪一部分,都可以开关 CheckBox 本身。

IsThreeState 属性

之前提到,CheckBox 通常对应一个布尔值,也就是说它只有两种状态——真与假,即启用与禁用。然而,布尔值也可以是空值,这就带来了第三种状态(真,假或空)。CheckBox 也支持第三种状态。如果把 IsThreeState 属性设为真,CheckBox 就会拥有第三种状态,被称作“不定态”。

IsThreeState 的一般用法是创建一个“全部启用”的 CheckBox,让它控制一系列的子 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 也会一起被勾选或取消。反过来看也成立:单独操作子 CheckBox 也会影响“全部启用” CheckBox 的状态。如果子 CheckBox 全部被勾选或取消,“全部启用” CheckBox 就会获得对应的状态。但要是子 CheckBox 的状态不统一,“全部启用” CheckBox 的值就会为空值,令它进入不定态。

所有这些特性都在上方的截图里,通过订阅 CheckBox 控件的 Checked 和 Unchecked 事件来实现。在现实世界中,你可能会直接绑定这些值,但这个例子是一个最基本的、利用 IsThreeState 属性来创建“全部启用”效果的实现。