3

我有一个MultiBinding转换器,它根据我的两个 Binding 字段是否都评估为 true 来确定控件的可见性。如果由于某种原因它无法达到这些布尔属性中的任何一个,我想将它们设置为评估为真。例如:

我目前拥有的代码是:

           <MultiBinding Converter="{StaticResource AndToVisibilityConverter1}" FallbackValue="Visible">
              <Binding Path="IsConnected" FallbackValue="true" />
              <Binding Path="CurrentUser.IsConsumerOnlyAgent" Converter="{StaticResource InvertedBooleanConverter1}" FallbackValue="True" />
           </MultiBinding>

代码运行良好,但是我在 IDE 的输出中收到错误消息,指示:

System.Windows.Data Error: 11 : Fallback value 'True' (type 'String') cannot be converted for use in 'Visibility' (type 'Visibility'). BindingExpression:Path=IsConnected; DataItem=null; target element is 'StackPanel' (Name=''); 

我已经确定了这个转换器并验证了它是 XAML 错误所在的位置。抱歉这里的无知,但是有没有办法将 FallbackValue 设置为这些绑定中的每一个,以便在无法获取设置路径时评估为“true”?提前致谢

更新:

这是我的可见性转换器的代码(我在整个应用程序的几个地方都使用了它,只是想添加回退值):

   internal class AndToVisibilityConverter : IMultiValueConverter
  {
  public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
  {
     if (values == null)
        return Visibility.Collapsed;

     foreach (var value in values)
     {
        if (value == null || !(value is bool))
           return Visibility.Collapsed;

        if (!((bool) value))
           return Visibility.Collapsed;
     }

     return Visibility.Visible;
  }

  public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
  {
     throw new NotImplementedException();
  }
  }
4

2 回答 2

15

FallbackValue值应该是Visibility绑定失败时回退的值:

<Binding Path="CurrentUser.IsConsumerOnlyAgent" 
    Converter="{StaticResource InvertedBooleanConverter1}" 
                FallbackValue="Visible" />

编辑

来自FallbackValue 文档

fallbackValue
与目标属性具有相同类型的属性或对象元素值。有关 XAML 使用信息,请参阅该类型的文档。该类型可能支持也可能不支持其值的属性语法,或者可能支持也可能不支持对象元素语法(这需要该类型的默认构造函数)。因此,目标属性类型将影响您为 FallbackValue 属性的值使用的语法。

在这种情况下,MultiBinding 的目标属性是 Visibility 属性。即使子 MultiBinding 属性的值需要一个 bool,父 MultiBinding 也需要一个来自绑定的 Visiblity 值。这意味着每个 MultiBinding 属性的 FallbackValue 都应具有 Visibility 属性的 FallbackValue。

似乎有点违反直觉,但仔细考虑(IMO)时确实有意义,re:如果 MultiBindng 上没有转换器,则绑定的返回值应该是 Visibility 值。从等式中删除转换器,它可能有助于解决问题。

对于您的情况,跳过每个 MultiBinding 值的 FallbackValue 并像现在一样在 MultiBinding 上设置 FallbackValue。

<MultiBinding Converter="{StaticResource AndToVisibilityConverter1}" FallbackValue="Visible">
    <Binding Path="IsConnected" />
    <Binding Path="CurrentUser.IsConsumerOnlyAgent" Converter="{StaticResource InvertedBooleanConverter1}" />
</MultiBinding>
于 2013-01-09T01:40:01.380 回答
5

经过一些测试,似乎当 MultiBinding 中的“子绑定”失败(由于 UnsetValue 或未能找到绑定属性)时,子绑定的 FallbackValues 被传递到 MultiBinding 上的转换器。

奇怪的是,子绑定上的 FallbackValue 的类型需要与MultiBinding的目标相匹配。我不明白这个要求,因为 MultiBinding 转换器可以从与该类型不匹配的绑定中获取值。

考虑到这一点,最简单的解决方法是修改 MultiBinding 的转换器以处理多种类型。在这种情况下,它需要处理布尔值和可见性。

即,我的转换函数如下所示:

    public object Convert( object[] values, Type targetType, object     parameter, System.Globalization.CultureInfo culture )
    {
        var bools = values.Where( b => b is bool ).Cast<bool>();
        var vis = values.Where( v => v is Visibility ).Cast<Visibility>();

        // if no usable values, return unset
        if( vis.Count() + bools.Count() == 0 )
            return DependencyProperty.UnsetValue;

        // if true, return visible
        if( bools.All( b => b ) && vis.All( v => v == Visibility.Visible ) )
            return Visibility.Visible;

        // if false, see if hidden or collapsed is specified
        var param = parameter as string;

        Visibility ret;
        if( Enum.TryParse( param, out ret ) )
            return ret;

        // default to collapsed
        return Visibility.Collapsed;
    }

此解决方法应通过将 Visible 指定为 true 并将其他内容指定为 false 来提供请求的行为:

    <MultiBinding Converter="{x:Static con:MultiAndToVisibilityConverter.Instance}">
        <Binding Path="IsChecked" ElementName="CheckButton"/>
        <Binding Path="RadioOne.IsChecked" FallbackValue="{x:Static Visibility.Visible}"
                 Converter="{x:Static con:BoolInverterConverter.Instance}"/>
    </MultiBinding>
于 2013-09-04T19:19:28.490 回答