2010-12-14 3 views
6

У меня есть флажок «Все», который я хотел бы связать с (IsChecked ||! IsEnabled) из других флажков.WPF Bind Checkbox IsChecked для других флажков (IsChecked ||! IsEnabled)

  • Проверка «Все» проверяет все включенные флажки.

  • Устранение отметки «Все» отменяет все флажки.

  • Ручная проверка каждого включенного флажка проверяет флажок «Все».

  • Когда все активированные флажки и «Все» отмечены флажком и пользователь отменяет любой флажок, «Все» автоматически отменяется.

Я новичок в привязке WPF. Я думал, может быть, я просто обрабатываю щелчок «Все», чтобы установить другие флажки. Но я не знаю, как привязать оба свойства нескольких источников. Когда я нажимаю «Все» и вручную снимите галочку с другого флажка, «Все» необходимо снять флажок.

ответ

12

Вот как это сделать в 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; 
    } 
} 
+0

Это замечательно. Мне не нужно было снять флажок или другой конвертер, и я отключил триггер для отключения. Однако я бы хотел, чтобы другие флажки могли быть отключены. Они не должны проверяться при отключении, но они не будут засчитываться против проверки. Например, . Если флажок 2 отключен, нажатие кнопки «Проверить все» не проверяет. И если флажок Checkbox1/3 отмечен, отметьте «Проверить все». – TrevDev

+0

Да, вот что я подумал :) Один флажок должен делать это, так как он работает в обоих направлениях, я пропущу вопрос. Я обновлю свой ответ и посмотрю на ваши комментарии –

+0

Спасибо! Я начал играть с тем, что вы дали. Я сделал это беспорядочным, сделав один способ привязки к свойству IsEnabled. При преобразовании отмеченного флажка я проверяю i + 1 для свойства hew, включенного oneway. Его беспорядочный, и я не видел способ игнорировать отключенные флажки при обратном преобразовании. Мне любопытно увидеть ваше предлагаемое решение. – TrevDev

1

Я бы создать ViewModel позади вашего View класса с помощью шаблона проектирования MVVM: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

Тогда на вашем ViewModel (которые должны будут осуществлять INotifyPropertyChanged), вы можете иметь несколько bool свойств, по одному для каждого CheckBox и другое для всех из них:

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

Нехорошее решение IMO. Что делать, если есть 50 флажков? –