2010-12-14 5 views
6

다른 확인란의 (IsChecked ||! IsEnabled)에 바인딩하려는 '모두'확인란을 선택했습니다.WPF 바인딩 체크 상자를 다른 체크 상자에 IsChecked했습니다. (IsChecked ||! IsEnabled)

  • '모두'를 선택하면 사용 가능한 모든 확인란이 선택됩니다.

  • '모두'의 선택을 취소하면 모든 체크 박스의 선택이 취소됩니다.

  • 사용 가능한 각 확인란을 수동으로 선택하면 '모두'가 선택됩니다.

  • 사용 가능한 모든 확인란과 '모두'가 선택되고 사용자가 모든 확인란의 선택을 취소하면 '모두'가 자동으로 선택 취소됩니다.

저는 WPF Databinding을 처음 사용합니다. 다른 체크 박스를 설정하기 위해 '모든'클릭 만 처리한다고 생각했습니다. 하지만 여러 소스의 두 속성에 바인딩하는 방법을 모르겠습니다. '모두'를 클릭하고 수동으로 다른 확인란의 선택을 취소하면 '모두'의 선택을 취소해야합니다.

답변

12

여기는 변환기가있는 Xaml에서 수행하는 방법입니다. 이것은 모든 CheckBox가 Xaml에서 컨트롤로 직접 추가되었다고 가정합니다 (매우 동적이지 않고 DataTemplate 등에서 작동하지 않습니다). 먼저 CheckAllCheckBox를 검사 할 때 Checked/Checked 될 3 개의 CheckBoxes (CheckBox1, CheckBox2, CheckBox3)를 만듭니다. 또한 역으로 작동합니다.

업데이트
마지막 부분 (사용 안 함 확인란을 무시) 약간의 문제가 여기에 있었고, 난이 솔루션에 대한 미치지 않았어하지만 난 더 나은 방법을 볼 수 없습니다. Convert에서 값을 저장하고 비활성화 된 CheckBox의 ConvertBack에서 값을 다시 사용합니다. 이 일을, 우리는 또한 X 추가해야합니다 : 새 인스턴스가 그것을 사용하는 것이 그 모든 MultiBinding 필요하기 때문에 CheckAllConverter에 대한 공유가 = "거짓"속성을 (여전히이 경우 가능성이 있지만 ..)

<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이 선택되면 Check All이 선택됩니다. – TrevDev

+0

예, 그게 내가 생각한 것입니다 : 두 가지 방법으로 작동하기 때문에 하나의 체크 박스가 있어야합니다. 나는 질문을 잘못 읽었습니다. 내 대답을 업데이트하고 의견을 보겠습니다. –

+0

감사합니다! 나는 네가 준 것과 놀기 시작했다. IsEnabled 속성에 바인딩하는 편도를 만들어 난잡하게 만들었습니다. 체크되지 않은 체크 박스를 변환 할 때 나는 oneway enabled 속성 heh에 대해 i + 1을 체크한다. 그것의 지저분한 그리고 내가 다시 변환 할 때 비활성화 된 확인란을 무시하는 방법을 보지 못했어요. 나는 당신의 제안 된 해결책을보고 싶다. – TrevDev

1

나는 MVVM 디자인 패턴을 사용하여 View 클래스 뒤에 뷰 모델을 만들 것입니다 : http://msdn.microsoft.com/en-us/magazine/dd419663.aspx에 다음

당신의 ViewModel (에서 INotifyPropertyChanged를 구현해야 할) 당신은, 각각의 체크 박스 하나와 다른 여러 bool 특성을 가질 수있다 그들 모두를위한 :

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

좋은 해결책이 아닙니다. 50 개의 체크 박스가 있다면 어떨까요? –

관련 문제