强制三态复选框不移动到不确定状态

时间:2010-10-13 04:26:55

标签: wpf checkbox

我在WPF工作,我有一个有趣的要求。 我需要我的复选框是ThreeState,所以如果只选择了一些子元素,它会显示为不确定。但是当用户点击它时,我希望它选择true或false。

这是一个代表我的要求的故事:

item - indeterminate  
    subItem - checked  
    subItem - unchecked  
    subItem - checked  

当用户点击item时,该复选框应在已选中和未选中之间切换。用户永远不能选择“不确定”作为状态。这可能吗?

2 个答案:

答案 0 :(得分:17)

XAML:

<CheckBox IsThreeState="True" IsChecked="{x:Null}" Click="CheckBox_Clicked" />

代码隐藏:

private void CheckBox_Clicked(object sender, RoutedEventArgs e)
  {
     var cb = e.Source as CheckBox;
     if (!cb.IsChecked.HasValue) 
        cb.IsChecked = false;
  }

如果您不喜欢代码隐藏解决方案,那么您可以像this问题的解决方案一样对您自己的控件进行子类化。

答案 1 :(得分:14)

如果你在CheckBox中使用Binding会更容易。

XAML:

<Window x:Class="WpfApplication39Checkbox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <CheckBox Content="CheckBox" HorizontalAlignment="Left" Margin="128,95,0,0" VerticalAlignment="Top" IsThreeState="False" IsChecked="{Binding CheckState}"/>
        <Button Content="Button" HorizontalAlignment="Left" Margin="46,241,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
        <Button Content="Button" HorizontalAlignment="Left" Margin="139,241,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
        <Button Content="Button" HorizontalAlignment="Left" Margin="235,241,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_2"/>
    </Grid>
</Window>

代码隐藏:

using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;

namespace WpfApplication39Checkbox
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }

        private bool? checkState;

        public bool? CheckState
        {
            get { return checkState; }
            set
            {
                checkState = value;
                OnPropertyChanged("CheckState");
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            CheckState = false;
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            CheckState = true;
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            CheckState = null;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

你明白了吗?您将CheckBox设置为IsThreeState =“False”,但是从CodeBehind设置第三个状态,CheckBox的行为与预期一致。