I have a WPF xaml file describing a section of a GUI and I'd like the enabling/disabling of a particular control to be dependent on two others. The code looks something like this at the moment:
<ComboBox Name="MyComboBox"
          IsEnabled="{Binding ElementName=SomeCheckBox, Path=IsChecked}"/>
But I'd like it to be dependant on another checkbox as well so something like:
<ComboBox Name="MyComboBox"
          IsEnabled="{Binding ElementName=SomeCheckBox&AnotherCheckbox, Path=IsChecked}"/>
What's the best way to go about that? I can't help feeling I'm missing something obvious or going about this the wrong way?
You can use a MultiBinding with a converter which implements IMultiValueConverter.
Just to give an answer you can (almost) copy&paste:
Static resource needed:
<converterNamespace:BooleanAndConverter x:Key="booleanAndConverter" />
The ComboBox:
<ComboBox Name="MyComboBox">
  <ComboBox.IsEnabled>
    <MultiBinding Converter="{StaticResource booleanAndConverter}">
      <Binding ElementName="SomeCheckBox" Path="IsChecked" />
      <Binding ElementName="AnotherCheckbox" Path="IsChecked"  />
    </MultiBinding>
  </ComboBox.IsEnabled>
</ComboBox>
The code for the converter:
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.");
        }
    }
}
                        You can also try shorter version of the same:
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();
    }
}
and, of course, you may need the converters for visibility, too:
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();
    }
}
                        I believe you may have to use a MultiBinding with a MultiValueConverter. See here: http://www.developingfor.net/wpf/multibinding-in-wpf.html
Here is a directly related example: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/5b9cd042-cacb-4aaa-9e17-2d615c44ee22
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With