C# WPF IsEnabled 使用多个绑定?

Posted

技术标签:

【中文标题】C# WPF IsEnabled 使用多个绑定?【英文标题】:C# WPF IsEnabled using multiple bindings? 【发布时间】:2010-10-31 00:48:06 【问题描述】:

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

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

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

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

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

【问题讨论】:

【参考方案1】:

您可以将MultiBinding 与实现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.");
        
    

【讨论】:

我有一个问题,如果 values 为 null 怎么办?一开始有这样的支票不是更好吗:if (values == null) return false; ConvertBack 方法应该返回 null 而不是抛出 NotSupportedException、according to MSDN。 在我看来,使用 LinQ 转换方法更容易理解:return values.All(value =&gt; value is bool &amp;&amp; (bool) value);return values.All(value =&gt; value is bool b &amp;&amp; b); 我知道这是旧的,但我使用了这种 LinQ 语法:return values.OfType&lt;bool&gt;().All(x =&gt; x); 如果我需要不同的转换器怎么办?【参考方案2】:

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

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

【讨论】:

有没有办法把这些链接起来?【参考方案3】:

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

【讨论】:

【参考方案4】:

作为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;
    

命名空间 &lt;theNamespace:IsEnabledConverter x:Key="IsEnabledConverter"/&gt;

按钮

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

【讨论】:

以上是关于C# WPF IsEnabled 使用多个绑定?的主要内容,如果未能解决你的问题,请参考以下文章

WPF 条件绑定。 Button.IsEnabled 到 SelectedIndex >= 0

如何将 WPF ListBoxItem 的 IsEnabled 属性绑定到其源项的属性?

C# 使按钮在两个条件为真后可见,可绑定属性

WPF XAML 在 IsEnabled 状态下更改图像不透明度

WPF Button isPressed 和 isEnabled 问题

将 IsEnabled 绑定到父 ViewModel 而不是 UserControl ViewModel