Вот как это сделать в Xaml с преобразователями. Предполагается, что все ваши CheckBox добавляются напрямую как элементы управления в Xaml (он не очень динамичен, не работает для DataTemplate и т. Д.). Сначала мы создаем три CheckBoxes (CheckBox1, CheckBox2, CheckBox3), которые будут проверены/сняты при проверке CheckAllCheckBox. Он также будет работать в обратном порядке.
Update
Последняя часть (игнорировать инвалид CheckBox) было немного проблемы здесь, и я не в восторге от этого решения, но я не могу видеть лучший путь. Мы сохраняем значения из Convert и повторно используем их в ConvertBack для отключенных CheckBox. Делая это, мы должны также добавить х: Shared = «False» атрибут для CheckAllConverter, так как новый экземпляр требуется для каждого MultiBinding, что бы использовать его (вряд ли в этом случае, но все же ..)
<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>
Конвертер для 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;
}
}
Это замечательно. Мне не нужно было снять флажок или другой конвертер, и я отключил триггер для отключения. Однако я бы хотел, чтобы другие флажки могли быть отключены. Они не должны проверяться при отключении, но они не будут засчитываться против проверки. Например, . Если флажок 2 отключен, нажатие кнопки «Проверить все» не проверяет. И если флажок Checkbox1/3 отмечен, отметьте «Проверить все». – TrevDev
Да, вот что я подумал :) Один флажок должен делать это, так как он работает в обоих направлениях, я пропущу вопрос. Я обновлю свой ответ и посмотрю на ваши комментарии –
Спасибо! Я начал играть с тем, что вы дали. Я сделал это беспорядочным, сделав один способ привязки к свойству IsEnabled. При преобразовании отмеченного флажка я проверяю i + 1 для свойства hew, включенного oneway. Его беспорядочный, и я не видел способ игнорировать отключенные флажки при обратном преобразовании. Мне любопытно увидеть ваше предлагаемое решение. – TrevDev