2010-04-19 14 views
8

Lo pregunto porque parece que no funciona.¿Cómo funciona FallbackValue con un enlace múltiple?

Supongamos que estamos unión con el siguiente objeto:

public class HurrDurr 
{ 
    public string Hurr {get{return null;}} 
    public string Durr {get{return null;}} 
} 

Bueno, parece que si se utilizó un MultiBinding contra de esto el valor de retorno se muestra, ¿verdad?

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

Sin embargo, el resultado es, de hecho, "a la". Incluso forzando los enlaces para volver DependencyProperty.UnsetValue no funciona:

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

intentado lo mismo con TargetNullValue, que también fue un fracaso en todos los sentidos.

lo que parece que MultiBinding nunca jamás usar FallbackValue. ¿Es esto cierto o me estoy perdiendo algo?


Un poco más de jugar un poco y me encontré con que un convertidor puede devolver el UnsetValue que necesito:

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."); 
    } 
} 

Sin embargo, esto parece un truco sucio sucio. Creo que un escenario como este se contabilizaría en el marco. Sin embargo, no puedo encontrar nada en Reflector.

+0

¡Buena pregunta! – Chris

Respuesta

7

Esta es una pregunta un poco vieja, pero podría usar alguna explicación.

Desde el FallbackValue documentation:

un enlace devuelve un valor éxito si:

  1. La ruta de acceso al origen de enlace resuelve con éxito.
  2. El convertidor de valor, si lo hay, puede convertir el valor resultante.
  3. El valor resultante es válido para la propiedad de destino de destino (destino).

Si 1 y 2 de retorno DependencyProperty.UnsetValue, la propiedad de destino se establece en el valor de la FallbackValue, si hay uno disponible. Si no hay FallbackValue, el valor predeterminado de la propiedad de destino es utilizado.

En el ejemplo proporcionado, la unión con éxito resuelve los Hurr y Durr propiedades. Nulo es un valor válido para una cadena, lo que significa que la vinculación es válida.

En otras palabras, FallbackValue se usa cuando el enlace no puede devolver un valor y en el ejemplo proporcionado, el enlace proporciona un valor válido.

Tomemos por ejemplo cada uno de los siguientes fragmentos que se basan fuera de la original ejemplo:

Ejemplo 1
Las propiedades Hurr y Durr están unidos correctamente; null es un valor válido y FallbackValue nunca se verá.

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

Ejemplo 2
Las propiedades Hurr y Durr no están obligados correctamente; se verá el valor de 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> 

Ejemplo 3
Si un camino enlace no es válido, entonces se verá la 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> 

Ejemplo 4
Como con los ejemplos previos, la unión es correcta, por lo que no se utilizará el FallbackValue. Además, FallbackValue para cada una de las propiedades secundarias Binding del padre MultiBinding debe referirse a un FallbackValue que se utilizará para la propiedad destino del MultiBinding, no para las vinculaciones secundarias.

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

Ejemplo 5
La unión sigue siendo válida a pesar de que un camino no se proporciona en Binding propiedades desde la unión va a utilizar cualquier objeto que está obligado a.

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

Ejemplo 6
Por último, si se añade un convertidor para cualquiera de las propiedades de unión para forzar una UnsetValue, entonces el MultiBinding FallbackValue será visto:

convertidor

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