51

我有一个描述 GUI 一部分的 WPF xaml 文件,我希望特定控件的启用/禁用依赖于其他两个控件。代码现在看起来像这样:

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

但我希望它也依赖于另一个复选框,例如:

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

最好的方法是什么?我不禁觉得我遗漏了一些明显的东西或以错误的方式解决这个问题?

4

4 回答 4

90

您可以将 aMultiBinding与实现IMultiValueConverter.

只是为了给出答案,您可以(几乎)复制和粘贴:

需要的静态资源:

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

组合框:

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

转换器的代码:

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.");
        }
    }
}
于 2013-10-06T14:40:08.123 回答
20

您也可以尝试相同的较短版本:

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

当然,您可能还需要转换器来提高可见性:

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();
    }
}
于 2016-07-12T20:20:27.440 回答
14

我相信您可能必须将 MultiBinding 与 MultiValueConverter 一起使用。见这里: http: //www.developingfor.net/wpf/multibinding-in-wpf.html

这是一个直接相关的示例:http ://social.msdn.microsoft.com/Forums/en-US/wpf/thread/5b9cd042-cacb-4aaa-9e17-2d615c44ee22

于 2009-06-03T15:36:21.990 回答
2

作为 qqbenq 答案的扩展:

添加了处理Count集合的功能,例如,如果您想检查是否选择了某个项目ListView

转换器:

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

命名空间 <theNamespace:IsEnabledConverter x:Key="IsEnabledConverter"/>

按钮

<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>
于 2018-08-15T08:29:26.627 回答