2010-11-17 8 views
48

Desidero formattare il binding della stringa come Amount is X dove X è una proprietà associata a un'etichetta.StringFormat WPF sul contenuto dell'etichetta

Ho visto molti esempi, ma il seguente non funziona:

<Label Content="{Binding Path=MaxLevelofInvestment, 
    StringFormat='Amount is {0}'}" /> 

Ho anche provato queste combinazioni:

StringFormat=Amount is {0} 
StringFormat='Amount is {}{0}' 
StringFormat='Amount is \{0\}' 

Ho anche provato a cambiare il tipo di dati della proprietà vincolante per int , string e double. Niente sembra funzionare. Questo è un caso d'uso molto comune ma non sembra essere supportato.

risposta

138

La ragione per cui questo non funziona è che la proprietà è di tipo Label.ContentObject e Binding.StringFormat viene utilizzato solo quando si esegue il binding a una proprietà di tipo String.

Quello che sta accadendo è:

  1. Il Binding è la boxe vostro valore MaxLevelOfInvestment e la memorizzazione della proprietà Label.Content come valore decimale in scatola.
  2. Il controllo Etichetta ha un modello che include uno ContentPresenter.
  3. Poichénon è impostato, ContentPresenter cerca un DataTemplate definito per il tipo Decimal. Quando non ne trova, utilizza un modello predefinito.
  4. Il modello predefinito utilizzato da ContentPresenter presenta stringhe utilizzando la proprietà ContentStringFormat dell'etichetta.

due soluzioni:

  • Uso Label.ContentStringFormat anziché Binding.StringFormat o
  • utilizzare una proprietà stringa come TextBlock.Text anziché Label.Content

Ecco come usare Label.ContentStringFormat:

<Label Content="{Binding Path=MaxLevelofInvestment}" ContentStringFormat="Amount is {0}" /> 

Ecco come utilizzare un TextBlock:

<TextBlock Text="{Binding Path=MaxLevelofInvestment, StringFormat='Amount is {0}'}" /> 

Nota: Per semplicità ho omesso un dettaglio nella spiegazione di cui sopra: Il ContentPresenter utilizza effettivamente le proprie Template e StringFormat proprietà, ma durante il caricamento di questi elementi viene automaticamente associato al modello delle proprietà ContentTemplate e ContentStringFormat dello Label, quindi sembra che lo ContentPresenter stia effettivamente utilizzando le proprietà dello Label.

+0

grazie per la spiegazione dettagliata, ora ha senso. fino alla squadra WPF per rendere questo pulito per il futuro. –

+0

Mi piace la tua risposta, sapresti come usare 2 parametri invece di solo 1? Davvero in difficoltà qui (come TextBlock stringFormat può gestire più quando si utilizzano i trigger, ecc.). – EricG

1

Provare a utilizzare un convertitore ....

<myconverters:MyConverter x:Key="MyConverter"/> 


<Label Content="{Binding Path=MaxLevelofInvestment, Converter={StaticResource MyConverter"} /> 


public class MyConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return String.Format("Amount is {0}", value); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return value; 
    } 
} 
+2

Questo non è necessario e nasconde il formato nel code-behind. – SLaks

+0

Forse sì, ma questo risolverà il problema. – Gabe

+3

È eccessivo. Spiego la causa del problema e presenti due semplici soluzioni nella mia risposta. –

3

Ho appena controllato e per qualche ragione non funziona con l'etichetta, probabilmente perché utilizza un ContentPresenter per la proprietà Content internamente. Puoi usare invece un TextBlock e questo funzionerà. Si potrebbe anche mettere il brano TextBlock sotto nel contenuto di un'etichetta, se avete bisogno di ereditare lo stile, il comportamento ecc

<TextBlock Text="{Binding Path=MaxLevelofInvestment, StringFormat='Amount is \{0\}'} /> 
2

Fai un universale StringFormatConverter : IValueConverter. Passa la stringa di formato come ConverterParameter.

Label Content="{Binding Amount, Converter={...myConverter}, ConverterParameter='Amount is {0}'" 

Inoltre, assicurarsi StringFormatMultiConverter : IMultiValueConverter quando avete bisogno di più di un oggetto in stringa di formato, per esempio, Completed {0} tasks out of {1}.

+0

Mi piace questo. Riesco a vedere il valore dell'utilizzo sia dell'approccio puro 'XAML' che del convertitore di valore. – IAbstract

Problemi correlati