Как работает FallbackValue с Multi-iinding?
-
28-09-2019 - |
Вопрос
Я спрашиваю, потому что это не работает.
Предположим, что мы обязательно с следующим объектом:
public class HurrDurr
{
public string Hurr {get{return null;}}
public string Durr {get{return null;}}
}
Ну, это появится, что если мы использовали Multibinding. Против этого последующее значение будет показано, верно?
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} to the {1}"
FallbackValue="Not set! It works as expected!)">
<Binding Path="Hurr"/>
<Binding Path="Durr"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
Однако результат, на самом деле, «На»Отказ Даже заставляют привязки вернуться DependencyProperty.UnsetValue
не работает:
<TextBlock xmnlns:base="clr-namespace:System.Windows;assembly=WindowsBase">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} to the {1}"
FallbackValue="Not set! It works as expected!)">
<Binding Path="Hurr"
FallbackValue="{x:Static base:DependencyProperty.UnsetValue}" />
<Binding Path="Durr"
FallbackValue="{x:Static base:DependencyProperty.UnsetValue}" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
Пробовал то же самое с Targetnullvalue., который был также бюстом в целом.
Так что кажется, что Multibinding. никогда не будет использовать FallbackValue.. Отказ Это правда, или я что-то упускаю?
Немного больше возиться, и я обнаружил, что конвертер может вернуть INCETVALUE, мне нужно:
class MultiValueFailConverter : IMultiValueConverter
{
public object Convert(
object[] values,
Type targetType,
object parameter,
System.Globalization.CultureInfo culture)
{
if (values == null ||
values.Length != 2 ||
values.Any(x=>x == null))
return System.Windows.DependencyProperty.UnsetValue;
return values;
}
public object[] ConvertBack(
object value,
Type[] targetTypes,
object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException("Too complex hurt brain.");
}
}
Однако это кажется грязным взломом. Я бы подумал, что сценарий будет учитываться в рамках. Однако я не могу найти в отражателе.
Решение
Это немного старого вопроса, но это может использовать некоторые объяснения.
Из DelabbackValue Документация:
Привязка успешно возвращает значение:
- Путь к источнику связывания разрешается успешно.
- Преобразователь стоимости, если таковая имеется, может преобразовать полученное значение.
- Результирующее значение является действительным для свойства связывания целевой целевой (целевой).
Если 1 и 2 возвращаемая зависимостьPROPERTY.unsetValue, целевое свойство устанавливается на значение FallcackValue, если он доступен. Если используется FallbackValue, используется значение по умолчанию целевого свойства.
В приведенном примере привязка успешно разрешается к Hurr
а также Durr
характеристики. NULL является допустимым значением для строки, которая означает, что связывание действительна.
Другими словами, FallcackValue используется, когда привязка не может вернуть значение, и в приведенном приведенном приведенном примере привязка обеспечивает допустимое значение.
Возьмите, например, каждая из следующих фрагментов, основанных на исходном примере:
Пример 1.
Свойства Hurr и Durr связаны правильно; NULL - это правильное значение, а FallcaBackValue никогда не будет видеть.
<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.
Свойства Hurur и 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.
Как и в случае с предыдущими примерами, связывание является правильным, поэтому FallcackValue не будет использоваться. Далее, FallcackValue для каждого из ребенка Binding
свойства MultiBinding
Родитель должен относиться к FallcackValue, который будет использоваться для целевого свойства 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.
Наконец, если преобразователь добавляется к любому из свойств привязки, чтобы заставить неконтролируемое, то будет замечен 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>