2010-12-14 18 views
6

Tengo una casilla de selección 'Todos' que me gustaría que esté vinculada a (IsChecked ||! IsEnabled) de otras casillas de verificación.WPF Vincular casilla de verificación está comprobado a otras casillas de verificación (IsChecked ||! IsEnabled)

  • Comprobación 'Todos' comprueba todas las casillas habilitadas.

  • Al quitar la marca "Todo" se desmarcan todas las casillas de verificación.

  • Al marcar manualmente cada casillero habilitado, se marcará 'Todos'.

  • Cuando todas las casillas habilitadas y 'Todas' están marcadas y el usuario desmarca cualquier casilla, 'Todas' se desmarca automáticamente.

Soy nuevo en WPF Databinding. Estaba pensando que quizás solo maneje el clic de 'Todos' para establecer las otras casillas de verificación. Pero no sé cómo vincular ambas propiedades de múltiples fuentes. Cuando hago clic en 'Todo' y desactivo manualmente otra casilla, 'Todo' debe desmarcarse.

Respuesta

12

Esta es una forma de hacerlo en Xaml con convertidores. Esto supone que todos sus CheckBox se agregan directamente como controles en Xaml (no es muy dinámico, no funcionará para DataTemplate, etc.). Primero creamos tres CheckBoxes (CheckBox1, CheckBox2, CheckBox3) que se marcarán/desmarcarán cuando se compruebe CheckAllCheckBox. También funcionará a la inversa.

actualización
La última parte (ignorar CheckBox desactivado) era un poco de un problema aquí y no estoy loco por esta solución, pero no puedo ver una mejor manera. Almacenamos los valores de Convert y los reutilizamos en ConvertBack para los CheckBox desactivados. Al hacer esto, hay que añadir el directorio x: Compartido = atributo "falso" para el CheckAllConverter ya que se requiere una nueva instancia para cada MultiBinding que usarlo (poco probable en este caso, pero todavía ..)

<Window.Resources> 
    <local:CheckAllConverter x:Key="CheckAllConverter" x:Shared="False"/> 
</Window.Resources> 
<StackPanel> 
    <CheckBox Content="Check All" 
       Name="CheckAllCheckBox"> 
     <CheckBox.IsChecked> 
      <MultiBinding Converter="{StaticResource CheckAllConverter}"> 
       <Binding ElementName="CheckBox1" Path="IsChecked" /> 
       <Binding ElementName="CheckBox1" Path="IsEnabled" Mode="OneWay"/> 
       <Binding ElementName="CheckBox2" Path="IsChecked" /> 
       <Binding ElementName="CheckBox2" Path="IsEnabled" Mode="OneWay"/> 
       <Binding ElementName="CheckBox3" Path="IsChecked" /> 
       <Binding ElementName="CheckBox3" Path="IsEnabled" Mode="OneWay"/> 
      </MultiBinding> 
     </CheckBox.IsChecked> 
    </CheckBox> 
    <CheckBox Content="CheckBox 1" 
       Name="CheckBox1"/> 
    <CheckBox Content="CheckBox 2" 
       Name="CheckBox2"/> 
    <CheckBox Content="CheckBox 3" 
       Name="CheckBox3"/> 
</StackPanel> 

El Convertidor para CheckAll

public class CheckAllConverter : IMultiValueConverter 
{ 
    private object[] convertValues = null; 
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     convertValues = new object[values.Length]; 
     for(int i = 0; i < values.Length; i++) 
     { 
      convertValues[i] = values[i]; 
     } 

     for (int i = 0; i < values.Length; i += 2) 
     { 
      bool isChecked = (bool)values[i]; 
      bool isEnabled = (bool)values[i + 1]; 
      if (isEnabled == false) 
      { 
       continue; 
      } 
      if (isChecked == false) 
      { 
       return false; 
      } 
     } 
     return true; 
    } 
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) 
    { 
     object[] values = new object[targetTypes.Length]; 
     for (int i = 0; i < values.Length; i += 2) 
     { 
      if (convertValues != null && (bool)convertValues[i + 1] == false) 
      { 
       values[i] = convertValues[i]; 
      } 
      else 
      { 
       values[i] = value; 
      } 
      // IsEnabled is OneWay and won't care about this value 
      values[i + 1] = null; 
     } 
     return values; 
    } 
} 
+0

Esto es genial. No necesité la casilla de verificación desmarcar o el otro convertidor y eliminé el disparador para desactivarlo. Sin embargo, me gustaría permitir que las otras casillas de verificación puedan ser deshabilitadas. No deben marcarse cuando están desactivados, pero no contarán contra el cheque. Por ejemplo. Si Checkbox 2 está desactivado, al hacer clic en Verificar todo no se verificará. Y si marque Checkbox1/3, se marcará Verificar todo. – TrevDev

+0

Sí, eso es lo que pensé :) Una casilla de verificación debería hacerlo, ya que funciona en ambos sentidos, he leído mal la pregunta. Actualizaré mi respuesta y analizaré tus comentarios –

+0

¡Gracias! Empecé a jugar con lo que diste. Lo hice complicado haciendo un enlace de una manera a la propiedad IsEnabled. Al convertir una casilla de verificación sin marcar, verifico i + 1 para la propiedad habilitada de manera única heh. Es complicado y no vi una forma de ignorar las casillas de verificación desactivadas al convertir de nuevo. Tengo curiosidad por ver tu solución propuesta. – TrevDev

1

que crearía un modelo de vista detrás de la vista de clase utilizando el patrón de diseño MVVM: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

A continuación, en su modelo de vista (que tendrá que poner en práctica INotifyPropertyChanged) se pueden tener varias propiedades bool, uno para cada casilla de verificación y otra para todos ellos:

public bool IsChecked1 
{ 
    get 
    { 
     return isChecked1; 
    } 
    set 
    { 
     if (isChecked1 != value) 
     { 
      isChecked1 = value; 
      RaisePropertyChanged("IsChecked1"); 
      RaisePropertyChanged("AreAllChecked"); 
     } 
    } 
} 

// And so on 

public bool AreAllChecked 
{ 
    get 
    { 
     return IsChecked1 && IsChecked2; // etc. 
    } 
    set 
    { 
     if (AreAllChecked != value) 
     { 
      IsChecked1 = value; 
      IsChecked2 = value; 
      // etc. 
     } 
    } 
} 
+0

No es una buena solución IMO. ¿Qué pasa si hay 50 casillas de verificación? –

Cuestiones relacionadas