2012-04-02 9 views
8

Devo determinare il StringFormat di alcuni limiti TextBlocks in fase di esecuzione in base al sistema di unità identificato nell'oggetto da rilegare.IValueConverter con proprietà dipendenza dipendente

Ho un convertitore con una proprietà dipendenze che vorrei associare a. Il valore Bound viene utilizzato per determinare il processo di conversione.

public class UnitConverter : DependencyObject, IValueConverter 
{ 
    public static readonly DependencyProperty IsMetricProperty = 
     DependencyProperty.Register("IsMetric", typeof(bool), typeof(UnitConverter), new PropertyMetadata(true, ValueChanged)); 

    private static void ValueChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) 
    { 
     ((UnitConverter)source).IsMetric = (bool)e.NewValue; 
    } 

    public bool IsMetric 
    { 
     get { return (bool)this.GetValue(IsMetricProperty); } 
     set { this.SetValue(IsMetricProperty, value); } 
    } 

    object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (IsMetric) 
      return string.Format("{0:0.0}", value); 
     else 
      return string.Format("{0:0.000}", value); 
    } 

    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

dichiaro il convertitore

<my:UnitConverter x:Key="Units" IsMetric="{Binding Path=IsMetric}"/> 

e legare il TextBlock

<TextBlock Text="{Binding Path=Breadth, Converter={StaticResource Units}}" Style="{StaticResource Values}"/> 

Non di meno, ottengo il seguente errore:

System.Windows.Data errore: 2: Impossibile trovare il framework FrameworkElement o FrameworkContentElement per l'elemento di destinazione. BindingExpression: Path = IsMetric; DataItem = null; l'elemento target è 'UnitConverter' (HashCode = 62641008); La proprietà target è 'IsMetric' (tipo 'Boolean')

Immagino che questo sia inizializzato prima di impostare il datacontext e quindi non c'è nulla per associare la proprietà IsMetric a. Come posso ottenere il risultato desiderato?

risposta

6

A condizione che Breadth e IsMetric sono proprietà dello stesso oggetto dei dati, è possibile utilizzare un MultiBinding in combinazione con un multi value converter:

<TextBlock> 
    <TextBlock.Text> 
     <MultiBinding Converter="{StaticResource UnitMultiValueConverter}"> 
      <Binding Path="Breadth" /> 
      <Binding Path="IsMetric" /> 
     </MultiBinding> 
    </TextBlock.Text> 
</TextBlock> 

con un convertitore come questo:

public class UnitMultiValueConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     double value = (double)values[0]; 
     bool isMetric = (bool)values[1]; 
     string format = isMetric ? "{0:0.0}" : "{0:0.000}"; 
     return string.Format(format, value); 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Il problema con il tuo approccio è che quando UnitConverter viene dichiarato come risorsa non ha un DataContext e non ne arriverà mai più avanti.

E un'altra cosa importante: il callback ValueChanged per UnitConverter.IsMetric non ha senso. Imposta nuovamente la stessa proprietà che è stata appena modificata.

+0

Io volevo evitare questo perché ho centinaia di TextBlock e non volevo dover passare e modificarli tutti. –

+0

Grazie amico, mi sono reso conto che stavo proprio impostando la stessa proprietà, beh, se mai fosse stato chiamato così! Il MultiBinding funziona comunque –

Problemi correlati