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;
}
}
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
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 –
¡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