如何通过空对象防止 MultiBinding 链

How to prevent MultiBinding chain through null object

我有以下 XAML 代码:

        <TextBox Text="Image.Bytes" IsReadOnly="True"/>
        <TextBox IsReadOnly="True">
             <TextBox.Text>
                <MultiBinding Converter="{StaticResource ConcatTextConverter}" ConverterParameter="x">
                    <Binding Path="Image.Width"/>
                    <Binding Path="Image.Height"/>
                </MultiBinding>
            </TextBox.Text>
        </TextBox>
        

ConcatTextConverter 是一个简单的转换器,其作用如下:

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        string result = string.Empty;
        string separator = parameter?.ToString() ?? "";

        if(values?.Any() == true)
        {
            result = string.Join(separator, values);
        }

        return result;
    }

当 属性“图像”为空时,就会出现问题。 第一个文本框没有显示任何内容。

然而,第二个显示“DependencyProperty.UnsetValue}x{DependencyProperty.UnsetValue}”

输入转换器的值的类型为:values[0].GetType() {Name = "NamedObject" FullName = "MS.Internal.NamedObject"} System.Type {System.RuntimeType } 不幸的是,我无法访问这种类型 MS.Internal.NamedObject 以在发生这种情况时在转换器中对其进行过滤。

现在的问题是:当绑定链中的某个对象为空时,首先防止调用转换器的最佳方法是什么? - 或者其次:在转换器中识别此类“值”的最佳方法是什么?

您无法避免调用转换器,但您可以检查是否所有绑定都产生了值。

public object Convert(
    object[] values, Type targetType, object parameter, CultureInfo culture)
{
    string result = string.Empty;
    string separator = parameter?.ToString() ?? "";

    if (values.All(value => value != DependencyProperty.UnsetValue))
    {
        result = string.Join(separator, values);
    }

    return result;
}

您不需要转换器来连接字符串。您所需要的只是 MultiBinding 上的 StringFormat 属性。

此外,您不需要 TextBox。由于您已将其设置为 IsReadOnly="true",因此 TextBlock 会做同样的事情

当没有图像时,此绑定将为您提供一个空字符串

<TextBlock> 
    <TextBlock.Text>
        <MultiBinding StringFormat="{}{0}x{1}">
            <Binding Path="Image.Width"/>
            <Binding Path="Image.Height"/>
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

如果您在没有图像时想要一个字符串,例如“0x0”,您可以在各个绑定上使用“FallbackValue` 属性来实现这一点。

 <TextBlock> 
    <TextBlock.Text>
        <MultiBinding StringFormat="{}{0}x{1}">
            <Binding Path="Image.Width"   FallbackValue="0"/>
            <Binding Path="Image.Height"  FallbackValue="0"/>
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

编辑添加:FallbackValue 方法也适用于克莱门斯的优秀答案。无论您使用哪种方法,他提出的使您的转换器更强大的建议都是一件好事。