Это немного старый вопрос, но он может использовать некоторые объяснения.
Из документации FallbackValue :
Привязка возвращает значение успешно, если:
- Путь к источнику привязки разрешен успешно.
- Преобразователь значения, если таковой имеется, может преобразовать полученное значение.
- Полученное значение действительно для свойства target (target) привязки.
Если 1 и 2 возвращают DependencyProperty.UnsetValue, свойство target
устанавливается в значение FallbackValue, если оно доступно. Если
FallbackValue отсутствует, значением по умолчанию для целевого свойства является
б.
В приведенном примере привязка успешно разрешается в свойствах 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 не будет использоваться. Кроме того, FallbackValue для каждого из дочерних Binding
свойств родительского элемента MultiBinding
должен ссылаться на FallbackValue, который будет использоваться для целевого свойства MultiBinding, а не для дочерних привязок.
<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
Привязка все еще действительна, даже если путь не указан в свойствах Binding
, поскольку привязка будет использовать любой объект, с которым она связана.
<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>