How does FallbackValue work with a MultiBinding? How does FallbackValue work with a MultiBinding? wpf wpf

How does FallbackValue work with a MultiBinding?


This is a bit of an old question, but it could use some explanation.

From the 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.

In the example provided, the binding successfully resolves to the Hurr and Durr properties. Null is valid value for a string which means the binding is valid.

In other words, the FallbackValue is used when the binding is unable to return a value and in the example provided, the binding does provide a valid value.

Take for example each of the following snippets that are based off the original example:

Example 1
The Hurr and Durr properties are bound correctly; null is a valid value and the FallbackValue will never be seen.

<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>

Example 2
The Hurr and Durr properties are not bound correctly; the FallbackValue will be seen.

<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>

Example 3
If one binding path is invalid, then the FallbackValue will be seen.

<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>

Example 4
As with previous examples, the binding is correct, so the FallbackValue will not be used. Further, the FallbackValue for each of the child Binding properties of the MultiBinding parent should refer to a FallbackValue to be used for the target property of the MultiBinding, not for the child 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>

Example 5
The binding is still valid even though a path is not provided in Binding properties since the binding will use whatever object it is bound to.

<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>

Example 6
Finally, if a converter is added to any of the Binding properties to force an UnsetValue, then the MultiBinding FallbackValue will be seen:

Converter

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>