如何通过空对象防止 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
方法也适用于克莱门斯的优秀答案。无论您使用哪种方法,他提出的使您的转换器更强大的建议都是一件好事。
我有以下 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
方法也适用于克莱门斯的优秀答案。无论您使用哪种方法,他提出的使您的转换器更强大的建议都是一件好事。