Usa StringFormat per aggiungere una stringa a un'associazione XAML WPF


125

Ho un'applicazione WPF 4 che contiene un TextBlock che ha un'associazione unidirezionale a un valore intero (in questo caso, una temperatura in gradi Celsius). Il codice XAML ha questo aspetto:

<TextBlock x:Name="textBlockTemperature">
        <Run Text="{Binding CelsiusTemp, Mode=OneWay}"/></TextBlock>

Funziona bene per visualizzare il valore della temperatura effettiva, ma vorrei formattare questo valore in modo che includa ° C anziché solo il numero (30 ° C invece di soli 30). Ho letto di StringFormat e ho visto diversi esempi generici come questo:

// format the bound value as a currency
<TextBlock Text="{Binding Amount, StringFormat={}{0:C}}" />

e

// preface the bound value with a string and format it as a currency
<TextBlock Text="{Binding Amount, StringFormat=Amount: {0:C}}"/>

Sfortunatamente, nessuno degli esempi che ho visto ha aggiunto una stringa al valore associato come sto cercando di fare. Sono sicuro che deve essere qualcosa di semplice ma non ho fortuna a trovarlo. Qualcuno può spiegarmi come farlo?

Risposte:


218

Il tuo primo esempio è effettivamente ciò di cui hai bisogno:

<TextBlock Text="{Binding CelsiusTemp, StringFormat={}{0}°C}" />

20
Perché il formato stringa in xaml ha il vuoto iniziale {}?
Jonesopolis

6
@Jonesopolis È nei documenti, ma se la stringa di formato inizia con a {, fornisce un meccanismo per uscire, poiché {}ha già un significato in xaml.
Reed Copsey

5
Non vedo dove la documentazione spiega il {} principale.
Eric,

5
@Eric Come molta documentazione, fa schifo: lo dimostrano, ma non spiegano.
Reed Copsey

19
qui la documentazione del misterioso {}: msdn.microsoft.com/en-us/library/ms744986.aspx
Jotrius

107

Ecco un'alternativa che funziona bene per la leggibilità se hai il Binding nel mezzo della stringa o più associazioni:

<TextBlock>
  <Run Text="Temperature is "/>
  <Run Text="{Binding CelsiusTemp}"/>
  <Run Text="°C"/>  
</TextBlock>

<!-- displays: 0°C (32°F)-->
<TextBlock>
  <Run Text="{Binding CelsiusTemp}"/>
  <Run Text="°C"/>
  <Run Text=" ("/>
  <Run Text="{Binding Fahrenheit}"/>
  <Run Text="°F)"/>
</TextBlock>

6
Questa risposta mi piace un po 'di più perché posso inserire facilmente il testo da una libreria di stringhe. Ovviamente se sei davvero preoccupato per l'internazionalizzazione, probabilmente faresti meglio a usare un convertitore in modo che l'ordine del numero e delle unità non sia fisso. <Run Text = "{x: Static s: UIStrings.General_FahrenheitAbbreviation}" />
Matt Becker

1
Questa è un'ottima soluzione, ma ottengo spazi extra nella visualizzazione del testo finale, tra le sequenze di testo: qualche idea del perché? Nel tuo esempio vedo0 °C ( 32 °F)
Conrad il

Non è molto utile se si desidera eseguire la formattazione della stringa effettiva (ovvero controllare il numero di posizioni decimali, ecc.).
BrainSlugs83

5
@Conrad Se non vuoi gli spazi tra ogni esecuzione, dovresti mettere quelle corse su una singola riga come segue: <TextBlock> <Run Text = "{Binding CelsiusTemp}" /> <Run Text = "° C" / > <Run Text = "(" /: <Run Text = "{Binding Fahrenheit}" /> <Run Text = "° F)" /> </TextBlock>
Ladislav Ondris

94

Si noti che l'utilizzo di StringFormat in Bindings sembra funzionare solo per le proprietà "text". L'utilizzo di questo per Label.Content non funzionerà


16
Un punto MOLTO importante che mi ha portato a provarlo fino a quando non sono diventato disperato e ho trovato questo commento per convalidare il mio sospetto.
DonBoitnott

64
ContentStringFormatviene in soccorso, ad esempio: Content="{Binding Path=TargetProjects.Count}" ContentStringFormat="Projects: {0}".
Astrowalker

2
Grazie Casper, vero eroe per aver pubblicato queste informazioni.
DaWiseguy

5
per le intestazioni GridViewColumn, utilizzareHeaderStringFormat="{}{0} For Report"
Felix

2
Se stai usando i dati della fase di progettazione, sembra che tu debba ricostruire il progetto dopo aver modificato ContentStringFormat per fare in modo che le modifiche si riflettano nel designer, mentre StringFormat come usato su diciamo che una casella di testo aggiornerà il designer in tempo reale.
Richard Moore

-8

In xaml

<TextBlock Text="{Binding CelsiusTemp}" />

In ViewModelquesto modo, l'impostazione del valore funziona anche:

 public string CelsiusTemp
        {
            get { return string.Format("{0}°C", _CelsiusTemp); }
            set
            {
                value = value.Replace("°C", "");
              _CelsiusTemp = value;
            }
        }

19
Questo va contro il punto di vista della separazione View-Viewmodel
Askolein
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.