I have the following XAML code:
<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>
The ConcatTextConverter is a simple converter doing as follows:
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;
}
The Problem happens, when property "Image" is null. The first textbox just shows nothing as whished.
The second, however, shows "DependencyProperty.UnsetValue}x{DependencyProperty.UnsetValue}"
The values given into the converter are of type: values[0].GetType() {Name = "NamedObject" FullName = "MS.Internal.NamedObject"} System.Type {System.RuntimeType} Unfortunately I can't acces to this type MS.Internal.NamedObject to filter it in the converter in case of happening.
Now the Question is: What is the best way to prevent calling the converter in first place, when some object in the binding chain is null? - Or secondly: what would be the best approach to identify such "values" in the converter?
CodePudding user response:
You can't avoid that the converter is called, but you can check whether all of the Bindings did produce a value.
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;
}
CodePudding user response:
You do not need a converter to concatenate strings. All you need is a StringFormat
attribute on your MultiBinding.
Also, you do not need a TextBox
. Since you've set it to IsReadOnly="true"
, a TextBlock
would do the same thing
This binding will give you an empty string when there is no image
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}x{1}">
<Binding Path="Image.Width"/>
<Binding Path="Image.Height"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
If you instead would want a string like, say, "0x0" when there is no image, you could use "FallbackValue` attributes on the individual bindings to make that happen.
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}x{1}">
<Binding Path="Image.Width" FallbackValue="0"/>
<Binding Path="Image.Height" FallbackValue="0"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
Edited to add: The FallbackValue
approach also works with Clemens excellent answer. And his suggestion to make your converter more robust is a good thing to do regardless of which approach you use.