wpf – FallbackValue如何与MultiBinding一起使用?

我问,因为它似乎不起作用.

假设我们绑定到以下对象:

public class HurrDurr
{
  public string Hurr {get{return null;}}
  public string Durr {get{return null;}}
}

好吧,看来如果我们使用MultiBinding来反映这一点,就会显示回退值,对吗?

<TextBlock>
    <TextBlock.Text>                                
        <MultiBinding StringFormat="{}{0} to the {1}"
                        FallbackValue="Not set!  It works as expected!)">
            <Binding Path="Hurr"/>
            <Binding Path="Durr"/>
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

然而,结果实际上是“对”.
甚至强制绑定返回DependencyProperty.UnsetValue也不起作用:

<TextBlock xmnlns:base="clr-namespace:System.Windows;assembly=WindowsBase">
    <TextBlock.Text>                                
        <MultiBinding StringFormat="{}{0} to the {1}"
            FallbackValue="Not set!  It works as expected!)">
            <Binding Path="Hurr"
                FallbackValue="{x:Static base:DependencyProperty.UnsetValue}" />
            <Binding Path="Durr"
                FallbackValue="{x:Static base:DependencyProperty.UnsetValue}" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

与TargetNullValue一样尝试,这也是一个半身像.

所以似乎MultiBinding永远不会使用FallbackValue.这是真的吗,还是我错过了什么?

更麻烦一点,我发现转换器可以返回我需要的UnsetValue:

class MultiValueFailConverter : IMultiValueConverter
{
    public object Convert(
        object[] values, 
        Type targetType, 
        object parameter, 
        System.Globalization.CultureInfo culture)
    {
        if (values == null || 
            values.Length != 2 ||
            values.Any(x=>x == null))
            return System.Windows.DependencyProperty.UnsetValue;
        return values;
    }

    public object[] ConvertBack(
        object value, 
        Type[] targetTypes, 
        object parameter, 
        System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException("Too complex hurt brain.");
    }
}

然而,这似乎是一个肮脏的污秽黑客.我认为这样的场景将在框架中考虑.但是,我在Reflector中找不到任何东西.

这是一个老问题,但它可以使用一些解释.

FallbackValue documentation

A binding returns a value successfully if:

  1. The path to the binding source resolves successfully.
  2. The value converter, if any, is able to convert the resulting value.
  3. The resulting value is valid for the binding target (target) property.

If 1 and 2 return DependencyProperty.UnsetValue, the target property
is set to the value of the FallbackValue, if one is available. If
there is no FallbackValue, the default value of the target property is
used.

在提供的示例中,绑定成功解析为Hurr和Durr属性. Null是字符串的有效值,表示绑定有效.

换句话说,当绑定无法返回值时使用FallbackValue,并且在提供的示例中,绑定确实提供了有效值.

例如,以下每个基于原始示例的片段:

例1
Hurr和Durr属性绑定正确; null是一个有效值,永远不会看到FallbackValue.

<TextBlock>
    <TextBlock.Text>
        <MultiBinding FallbackValue="Binding is valid. I will never be seen." StringFormat="{}{0} to the {1}">
            <Binding Path="Hurr" />
            <Binding Path="Durr" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

例2
Hurr和Durr属性没有正确绑定;将会看到FallbackValue.

<TextBlock>
    <TextBlock.Text>
        <MultiBinding FallbackValue="Binding paths are invalid. Look at me." StringFormat="{}{0} to the {1}">
            <Binding Path="xHurr" />
            <Binding Path="xDurr" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

例3
如果一个绑定路径无效,则会看到FallbackValue.

<TextBlock>
    <TextBlock.Text>
        <MultiBinding FallbackValue="One binding path is invalid. Look at me." StringFormat="{}{0} to the {1}">
            <Binding Path="xHurr" />
            <Binding Path="Durr" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

例4
与前面的示例一样,绑定是正确的,因此不会使用FallbackValue.此外,MultiBinding父级的每个子Binding属性的FallbackValue应该引用一个FallbackValue,用于MultiBinding的target属性,而不是子Bindings.

<TextBlock xmlns:base="clr-namespace:System.Windows;assembly=WindowsBase">
    <TextBlock.Text>
        <MultiBinding FallbackValue="Binding is valid. I will never be seen." StringFormat="{}{0} to the {1}">
            <Binding FallbackValue="{x:Static base:DependencyProperty.UnsetValue}" Path="Hurr" />
            <Binding FallbackValue="{x:Static base:DependencyProperty.UnsetValue}" Path="Durr" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

例5
即使绑定属性中未提供路径,绑定仍然有效,因为绑定将使用绑定的任何对象.

<TextBlock xmlns:base="clr-namespace:System.Windows;assembly=WindowsBase">
    <TextBlock.Text>
        <MultiBinding FallbackValue="Binding is still valid. I will never be seen." StringFormat="{}{0} to the {1}">
            <Binding FallbackValue="{x:Static base:DependencyProperty.UnsetValue}" />
            <Binding FallbackValue="{x:Static base:DependencyProperty.UnsetValue}" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

例6
最后,如果将转换器添加到任何Binding属性以强制使用UnsetValue,则会看到MultiBinding FallbackValue:

变流器

internal class ForceUnsetValueConverter : IValueConverter
{
    #region Implementation of IValueConverter

    public object Convert( object value, Type targetType, object parameter, CultureInfo culture )
    {
        return DependencyProperty.UnsetValue;
    }

    public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture )
    {
        throw new NotImplementedException();
    }

    #endregion
}

XAML

<TextBlock>
    <TextBlock.Text>
        <MultiBinding FallbackValue="Binding is valid, but look at me. I'm an UnsetValue." StringFormat="{}{0} to the {1}">
            <Binding Converter="{StaticResource ForceUnset}" Path="Hurr" />
            <Binding Path="Durr" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>
相关文章
相关标签/搜索