2010-04-19 7 views
8

Ich frage, weil es nicht zu funktionieren scheint.Wie funktioniert FallbackValue mit einem MultiBinding?

Angenommen wir zu dem folgenden Objekt sind verbindlich:

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

Nun, es scheint, dass, wenn wir würden gezeigt ein Multibinding gegen das der Fehlerwert verwendet, nicht wahr?

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

aber das Ergebnis ist in der Tat, "zum". zwingt auch die Bindungen DependencyProperty.UnsetValue zurückzukehren funktioniert nicht:

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

die gleiche Versuchte mit TargetNullValue, die auch um eine Büste den ganzen Weg war.

So scheint es, dass Multibinding werden nieFallbackValue verwenden. Ist das wahr, oder fehlt mir etwas?


Ein wenig mehr rumgespielt und ich fand, dass ein Konverter die UnsetValue zurückkehren kann ich brauche:

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

Dies ist jedoch wie ein schmutziger schmutziger Hack scheint. Ich würde denken, dass ein Szenario wie dieses im Rahmen berücksichtigt würde. Ich kann jedoch nichts in Reflector finden.

+0

Gute Frage! – Chris

Antwort

7

Dies ist ein bisschen eine alte Frage, aber es könnte eine Erklärung verwenden.

Vom FallbackValue documentation:

ein verbindlichen liefert einen Wert erfolgreich, wenn:

  1. Der Weg zur Quelle Bindung löst erfolgreich.
  2. Der Wertwandler, falls vorhanden, kann den resultierenden Wert konvertieren.
  3. Der resultierende Wert ist für die Bindungsziel (ziel) -Eigenschaft gültig.

Wenn 1 und 2 Rück DependencyProperty.UnsetValue, die Zieleigenschaft auf den Wert des FallbackValue gesetzt ist, wenn eine verfügbar ist. Wenn kein FallbackValue vorhanden ist, wird der Standardwert der Zieleigenschaft verwendet.

In dem gegebenen Beispiel, löst die Bindung erfolgreich an die Hurr und Durr Eigenschaften. Null ist ein gültiger Wert für eine Zeichenfolge, was bedeutet, dass die Bindung gültig ist.

Mit anderen Worten, der FallbackValue wird verwendet, wenn die Bindung keinen Wert zurückgeben kann, und im angegebenen Beispiel liefert die Bindung einen gültigen Wert.

Nehmen Sie zum Beispiel jede der folgenden Schnipsel, die das ursprüngliche Beispiel basierend ausgeschaltet sind:

Beispiel 1
Die Hurr und Durr Eigenschaften korrekt gebunden sind; null ist ein gültiger Wert und der FallbackValue wird nie gesehen.

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

Beispiel 2
Die Hurr Durr und Eigenschaften nicht richtig gebunden sind; der FallbackValue wird gesehen.

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

Beispiel 3
Wenn eine Bindungspfad ungültig ist, dann wird der FallbackValue ersichtlich.

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

Beispiel 4
Wie bei den vorherigen Beispielen ist die Bindung richtig, so dass die FallbackValue wird nicht verwendet. Darüber hinaus sollte sich der FallbackValue für jede untergeordnete Binding-Eigenschaft des übergeordneten Elements MultiBinding auf einen FallbackValue beziehen, der für die Zieleigenschaft von MultiBinding und nicht für untergeordnete Bindungen verwendet wird.

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

Beispiel 5
Die Bindung ist immer noch gültig, auch wenn ein Pfad in Binding Eigenschaften nicht, da die zur Verfügung gestellt wird verbindlich verwenden, was Objekt, um es gebunden ist.

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

Beispiel 6
Schließlich, wenn ein Wandler nach einem der Bindungseigenschaften hinzugefügt wird, um eine UnsetValue zu zwingen, wird die Multibinding FallbackValue sehen:

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