2010-10-13 1 views
7

HI, Sto lavorando in WPF e ho un requisito interessante. Ho bisogno che le mie caselle di controllo siano ThreeState, quindi se solo alcuni degli elementi figli sono selezionati, viene mostrato come indeterminato. Ma quando un uso fa clic, voglio che selezioni vero o falso.Forzare una casella di controllo per non passare a uno stato indeterminato

Ecco una storia per rappresentare le mie esigenze:

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

Quando un utente fa clic item, la casella di controllo dovrebbe alternare controllato e incontrollato. L'utente non dovrebbe mai essere in grado di selezionare "indeterminato" come stato. È possibile?

risposta

17

XAML:

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

Codice-behind:

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

Se non ti piace il code-behind soluzione, allora si potrebbe sottoclasse il proprio controllo, come nella soluzione per this domanda.

+0

Bingo! grazie compagno. Provato con l'evento Indeterminato e non ha funzionato, ma cliccato fa ... strano :) – TerrorAustralis

12

È molto più semplice se usi Binding con il 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> 

Codice-behind:

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

si vede il punto? Si imposta il CheckBox su IsThreeState = "False" ma si imposta il terzo stato da CodeBehind e il CheckBox si comporta come previsto.