Verwenden Sie StringFormat, um einer WPF-XAML-Bindung einen String hinzuzufügen

124

Ich habe eine WPF 4-Anwendung, die einen TextBlock enthält, der eine Einwegbindung an einen ganzzahligen Wert (in diesem Fall eine Temperatur in Grad Celsius) hat. Die XAML sieht folgendermaßen aus:

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

Dies funktioniert gut für die Anzeige des tatsächlichen Temperaturwerts, aber ich möchte diesen Wert so formatieren, dass er ° C anstelle nur der Zahl enthält (30 ° C statt nur 30). Ich habe über StringFormat gelesen und einige allgemeine Beispiele wie dieses gesehen:

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

und

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

Leider hat keines der Beispiele, die ich gesehen habe, eine Zeichenfolge an den gebundenen Wert angehängt, wie ich es versuche. Ich bin sicher, es muss etwas Einfaches sein, aber ich habe kein Glück, es zu finden. Kann mir jemand erklären, wie das geht?

bmt22033
quelle

Antworten:

217

Ihr erstes Beispiel ist effektiv das, was Sie brauchen:

<TextBlock Text="{Binding CelsiusTemp, StringFormat={}{0}°C}" />
Reed Copsey
quelle
20
Warum hat das Zeichenfolgenformat in xaml das führende Leerzeichen {}?
Jonesopolis
6
@Jonesopolis Es ist in den Dokumenten - aber wenn Ihre Formatzeichenfolge mit a beginnt {, bietet es einen Mechanismus zum Escape, da {}es in xaml bereits eine Bedeutung hat.
Reed Copsey
5
Ich sehe nicht, wo die Dokumentation das führende {} erklärt.
Eric
5
@Eric Wie viele Dokumentationen stinkt es - sie demonstrieren es, erklären es aber nicht.
Reed Copsey
19
hier die Dokumentation des mysteriösen {}: msdn.microsoft.com/en-us/library/ms744986.aspx
Jotrius
106

Hier ist eine Alternative, die sich gut für die Lesbarkeit eignet, wenn Sie die Bindung in der Mitte der Zeichenfolge oder mehrere Bindungen haben:

<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>
denis morozov
quelle
6
Diese Antwort gefällt mir etwas besser, da ich problemlos Text aus einer Zeichenfolgenbibliothek einfügen kann. Wenn Sie sich wirklich Sorgen um die Internationalisierung machen, sollten Sie wahrscheinlich einen Konverter verwenden, damit die Reihenfolge der Anzahl und der Einheiten nicht festgelegt wird. <Run Text = "{x: Static s: UIStrings.General_FahrenheitAbbreviation}" />
Matt Becker
1
Dies ist eine großartige Lösung, aber ich erhalte zusätzliche Leerzeichen in der endgültigen Textanzeige zwischen den Textläufen - eine Idee warum? In Ihrem Beispiel sehe ich0 °C ( 32 °F)
Conrad
Es ist nicht besonders nützlich, wenn Sie eine tatsächliche Zeichenfolgenformatierung durchführen möchten (z. B. die Anzahl der Dezimalstellen steuern usw.).
BrainSlugs83
5
@Conrad Wenn Sie die Leerzeichen zwischen den einzelnen Läufen nicht möchten, sollten Sie diese Läufe wie folgt in eine einzelne Zeile einfügen: <TextBlock> <Run Text = "{Binding CelsiusTemp}" /> <Run Text = "° C" / > <Run Text = "(" /: <Run Text = "{Binding Fahrenheit}" /> <Run Text = "° F)" /> </ TextBlock>
Ladislav Ondris
91

Bitte beachten Sie, dass die Verwendung von StringFormat in Bindungen nur für "Text" -Eigenschaften zu funktionieren scheint. Die Verwendung für Label.Content funktioniert nicht

Casper Ehrenborg
quelle
15
Ein SEHR wichtiger Punkt, an dem ich es versucht habe, bis ich verzweifelt war und diesen Kommentar gefunden habe, um meinen Verdacht zu bestätigen.
DonBoitnott
64
ContentStringFormatkommt zur Rettung, Beispiel : Content="{Binding Path=TargetProjects.Count}" ContentStringFormat="Projects: {0}".
Astrowalker
2
Vielen Dank an Casper, den echten Helden, der diese Informationen veröffentlicht hat.
DaWiseguy
5
Verwenden Sie für GridViewColumn-HeaderHeaderStringFormat="{}{0} For Report"
Felix
2
Wenn Sie Entwurfszeitdaten verwenden, müssen Sie das Projekt anscheinend nach dem Bearbeiten von ContentStringFormat neu erstellen, damit Änderungen im Designer angezeigt werden, während StringFormat, wie es beispielsweise in einem Textfeld verwendet wird, den Designer in Echtzeit aktualisiert.
Richard Moore
-8

In xaml

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

Auf ViewModeldiese Weise funktioniert das Einstellen des Werts auch:

 public string CelsiusTemp
        {
            get { return string.Format("{0}°C", _CelsiusTemp); }
            set
            {
                value = value.Replace("°C", "");
              _CelsiusTemp = value;
            }
        }
Rajesh Nath
quelle
19
Dies widerspricht dem ganzen Punkt der View-Viewmodel-Trennung
Askolein