2009-06-03 15 views
32

Mam plik xaml WPF opisujący część GUI i chciałbym, aby włączanie/wyłączanie konkretnej kontroli było zależne od dwóch innych. Kod wygląda mniej więcej tak w tej chwili:C# WPF IsEnabled przy użyciu wielu powiązań?

<ComboBox Name="MyComboBox" 
      IsEnabled="{Binding ElementName=SomeCheckBox, Path=IsChecked}"/> 

Ale chciałbym to być zależne od innego wyboru, jak również tak coś jak:

<ComboBox Name="MyComboBox" 
      IsEnabled="{Binding ElementName=SomeCheckBox&AnotherCheckbox, Path=IsChecked}"/> 

Jaki jest najlepszy sposób, aby przejść o tym ? Nie mogę oprzeć się wrażeniu, że brakuje mi czegoś oczywistego lub źle to rozumiem?

Odpowiedz

54

Można użyć MultiBinding z konwerterem który implementuje IMultiValueConverter.

Wystarczy dać odpowiedź można (prawie) skopiować & pasty:

statyczny zasób potrzebne:

<converterNamespace:BooleanAndConverter x:Key="booleanAndConverter" /> 

ComboBox:

<ComboBox Name="MyComboBox"> 
    <ComboBox.IsEnabled> 
    <MultiBinding Converter="{StaticResource booleanAndConverter}"> 
     <Binding ElementName="SomeCheckBox" Path="IsChecked" /> 
     <Binding ElementName="AnotherCheckbox" Path="IsChecked" /> 
    </MultiBinding> 
    </ComboBox.IsEnabled> 
</ComboBox> 

Kod dla przetwornika:

namespace ConverterNamespace 
{ 
    public class BooleanAndConverter : IMultiValueConverter 
    { 
     public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      foreach (object value in values) 
      { 
       if ((value is bool) && (bool)value == false) 
       { 
        return false; 
       } 
      } 
      return true; 
     } 
     public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) 
     { 
      throw new NotSupportedException("BooleanAndConverter is a OneWay converter."); 
     } 
    } 
} 
+0

Mam jedno pytanie, co będzie, jeśli wartość jest null ? Czy nie jest lepiej mieć taki czek na początku: 'if (value == null) { return false; } ' ? – Devid

7

Możesz także spróbować krótszą wersję tego samego:

public class BooleanAndConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return values.OfType<IConvertible>().All(System.Convert.ToBoolean); 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotSupportedException(); 
    } 
} 

public class BooleanOrConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return values.OfType<IConvertible>().Any(System.Convert.ToBoolean); 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotSupportedException(); 
    } 
} 

i, oczywiście, może zaistnieć potrzeba konwerterów dla widoczności, zbyt:

public class BooleanOrToVisibilityConverter : IMultiValueConverter 
{ 
    public Visibility HiddenVisibility { get; set; } 

    public bool IsInverted { get; set; } 

    public BooleanOrToVisibilityConverter() 
    { 
     HiddenVisibility = Visibility.Collapsed; 
     IsInverted = false; 
    } 

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     bool flag = values.OfType<IConvertible>().Any(System.Convert.ToBoolean); 
     if (IsInverted) flag = !flag; 
     return flag ? Visibility.Visible : HiddenVisibility; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

public class BooleanAndToVisibilityConverter : IMultiValueConverter 
{ 
    public Visibility HiddenVisibility { get; set; } 

    public bool IsInverted { get; set; } 

    public BooleanAndToVisibilityConverter() 
    { 
     HiddenVisibility = Visibility.Collapsed; 
     IsInverted = false; 
    } 

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     bool flag = values.OfType<IConvertible>().All(System.Convert.ToBoolean); 
     if (IsInverted) flag = !flag; 
     return flag ? Visibility.Visible : HiddenVisibility; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 
Powiązane problemy