Forced switching of three states so as not to go into an undefined state

I work in WPF and I have an interesting requirement. I need my checkboxes to be ThreeState, so if only some of the children are selected, they are displayed as undefined. But when the user clicks on him, I want him to select either true or false.

Here is a story to present my requirements:

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

When the user clicks item , the flag should alternate between set and unchecked. The user should never be able to select "undefined" as the state. Is it possible?

+9
checkbox wpf
source share
2 answers

XAML:

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

Code for:

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

If you do not like the solution for the code, you can subclass your own control, as in the solution for this question.

+17
source share

This is much easier if you use Binding with your CheckBox.

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> 

Code for:

 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)); } } } 

Do you see the point? You set the CheckBox to IsThreeState = "False", but set the third state from CodeBehind and the CheckBox behaves as expected.

+14
source share

All Articles