C# WPF IsEnabled using multiple bindings?

流过昼夜 提交于 2019-12-17 18:14:45

问题


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?


回答1:


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




回答2:


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.");
        }
    }
}



回答3:


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();
    }
}



回答4:


As extension to qqbenq's answer:

Added the function to handle the Count of a Collection for example if you want to check if some item of a ListView is selected.

Converter:

public class IsEnabledConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        foreach (var value in values)
        {
            switch (value)
            {
                case bool b when !b:
                case int i when i == 0:
                    return false;
            }
        }

        return true;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        return null;
    }
}

Namespace <theNamespace:IsEnabledConverter x:Key="IsEnabledConverter"/>

Button

<Button x:Name="MyButton">
    <Button.IsEnabled>
        <MultiBinding Converter="{StaticResource IsEnabledConverter}">
            <Binding ElementName="MyListView" Path="SelectedItems.Count"/>
            <Binding ElementName="MyCheckBox" Path="IsChecked"/>
        </MultiBinding>
    </Button.IsEnabled>
</Button>


来源:https://stackoverflow.com/questions/945427/c-sharp-wpf-isenabled-using-multiple-bindings

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!