首页 文章

C#WPF IsEnabled使用多个绑定?

提问于
浏览
39

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

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

但我希望它依赖于另一个复选框,所以类似于:

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

最好的方法是什么?我情不自禁地觉得我错过了一些明显的东西或者错误的方式?

4 回答

  • 12

    我相信您可能必须使用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

  • 62

    您可以将MultiBinding与实现IMultiValueConverter的转换器一起使用 .

    只需给出答案,您就可以(几乎)复制并粘贴:

    需要的静态资源:

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

    转换器的代码:

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

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

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

    作为qqbenq答案的扩展:

    添加了处理Collection的 Count 的函数,例如,如果要检查是否选择了 ListView 的某个项目 .

    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>
    

相关问题