2010-04-19 15 views
8

Je demande parce que cela ne semble pas fonctionner.Comment FallbackValue fonctionne avec MultiBinding?

On suppose nous lier à l'objet suivant:

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

Eh bien, il semblerait que si nous avons utilisé un MultiBinding contre ce la valeur de repli serait montrée, non?

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

Toutefois, le résultat est, en fait, "à la". Même forcer les liaisons à retourner DependencyProperty.UnsetValue ne fonctionne pas:

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

Essayé la même chose avec TargetNullValue, qui était aussi un buste tout autour.

Il semble donc que MultiBinding ne jamais utiliser FallbackValue. Est-ce vrai ou ai-je oublié quelque chose?


Un peu plus de déconner et j'ai trouvé qu'un convertisseur peut retourner le UnsetValue j'ai besoin:

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

Cependant, cela semble être un hack crasseuse. Je pense qu'un scénario comme celui-ci serait pris en compte dans le cadre. Cependant, je ne trouve rien dans Reflector.

+0

Bonne question !! – Chris

Répondre

7

Ceci est un peu une vieille question, mais il pourrait utiliser quelques explications.

De l'FallbackValue documentation:

A rendements de liaison d'une valeur avec succès si:

  1. Le chemin vers la source de liaison résout avec succès.
  2. Le convertisseur de valeur, le cas échéant, est capable de convertir la valeur résultante.
  3. La valeur résultante est valide pour la propriété cible (cible) de liaison.

Si 1 et 2 retour DependencyProperty.UnsetValue, la propriété cible est définie sur la valeur du FallbackValue, si l'on est disponible. Si il n'y a pas FallbackValue, la valeur par défaut de la propriété target est utilisée.

Dans l'exemple fourni, la liaison résout avec succès aux Hurr et Durr propriétés. Null est une valeur valide pour une chaîne, ce qui signifie que la liaison est valide. En d'autres termes, la valeur FallbackValue est utilisée lorsque la liaison est incapable de renvoyer une valeur et, dans l'exemple fourni, la liaison fournit une valeur valide.

Prenons par exemple chacun des extraits suivants qui sont basés hors exemple d'origine:

Exemple 1
Les propriétés hurr et Durr sont liés correctement; null est une valeur valide et le FallbackValue ne sera jamais vu.

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

Exemple 2
Les propriétés hurr et Durr ne sont pas liés correctement; le FallbackValue sera vu.

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

Exemple 3
Si un chemin de liaison est invalide, le FallbackValue on le verra.

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

Exemple 4
Comme exemples précédents, la liaison est correcte, de sorte que le FallbackValue ne sera pas utilisé. En outre, la propriété FallbackValue pour chacune des propriétés enfant Binding du parent MultiBinding doit faire référence à une valeur FallbackValue à utiliser pour la propriété target de MultiBinding, et non pour les liaisons enfants.

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

Exemple 5
La liaison est toujours valide même si un chemin est pas fourni dans Binding propriétés puisque la liaison utilisera tout objet qu'il est lié.

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

Exemple 6
Enfin, si un convertisseur est ajouté à l'une des propriétés de liaison pour forcer un UnsetValue, le MultiBinding FallbackValue verra:

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>