Gunakan StringFormat untuk menambahkan string ke pengikatan WPF XAML

125

Saya memiliki aplikasi WPF 4 yang berisi TextBlock yang memiliki pengikatan satu arah ke nilai integer (dalam hal ini, suhu dalam derajat Celcius). XAML terlihat seperti ini:

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

Ini berfungsi dengan baik untuk menampilkan nilai suhu sebenarnya tetapi saya ingin memformat nilai ini sehingga mencakup ° C daripada hanya angka (30 ° C, bukan hanya 30). Saya telah membaca tentang StringFormat dan saya telah melihat beberapa contoh umum seperti ini:

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

dan

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

Sayangnya, tidak ada contoh yang saya lihat yang menambahkan string ke nilai terikat seperti yang saya coba lakukan. Saya yakin itu pasti sesuatu yang sederhana tetapi saya tidak beruntung menemukannya. Adakah yang bisa menjelaskan kepada saya bagaimana melakukan itu?

bmt22033
sumber

Jawaban:

218

Contoh pertama Anda secara efektif adalah apa yang Anda butuhkan:

<TextBlock Text="{Binding CelsiusTemp, StringFormat={}{0}°C}" />
Reed Copsey
sumber
20
Mengapa format string di xaml memiliki awalan kosong {}?
Jonesopolis
6
@Jonesopolis Ini ada di dokumen - tetapi jika string format Anda dimulai dengan a {, ini menyediakan mekanisme untuk melarikan diri, karena {}sudah memiliki arti di xaml.
Reed Copsey
5
Saya tidak melihat di mana dokumentasi menjelaskan memimpin {}.
Eric
5
@Eric Seperti banyak dokumentasi, itu bau - mereka mendemonstrasikannya, tapi tidak menjelaskan.
Reed Copsey
19
di sini dokumentasi misterius {}: msdn.microsoft.com/en-us/library/ms744986.aspx
Jotrius
107

Berikut adalah alternatif yang berfungsi dengan baik agar mudah dibaca jika Anda memiliki Binding di tengah-tengah string atau beberapa binding:

<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
sumber
6
Saya menyukai jawaban ini sedikit lebih baik karena saya dapat memasukkan teks dari pustaka string dengan mudah. Tentu saja jika Anda benar-benar khawatir tentang internasionalisasi, Anda mungkin lebih baik menggunakan pengubah sehingga urutan nomor dan satuannya tidak tetap. <Run Text = "{x: Static s: UIStrings.General_FahrenheitAbbreviation}" />
Matt Becker
1
Ini adalah solusi yang bagus, tetapi saya mendapatkan spasi ekstra di tampilan teks akhir, di antara Text Runs - tahu mengapa? Dalam contoh Anda, saya melihat0 °C ( 32 °F)
Conrad
Ini tidak terlalu berguna jika Anda ingin melakukan pemformatan string yang sebenarnya (yaitu mengontrol jumlah tempat desimal, dll.).
BrainSlugs83
5
@Conrad Jika Anda tidak ingin spasi di antara setiap proses, Anda harus menempatkan proses tersebut pada satu baris sebagai berikut: <TextBlock> <Run Text = "{Binding CelsiusTemp}" /> <Run Text = "° C" / > <Run Text = "(" /: <Run Text = "{Binding Fahrenheit}" /> <Run Text = "° F)" /> </TextBlock>
Ladislav Ondris
94

Harap perhatikan bahwa menggunakan StringFormat di Bindings sepertinya hanya berfungsi untuk properti "teks". Menggunakan ini untuk Label.Content tidak akan berfungsi

Casper Ehrenborg
sumber
16
Sebuah SANGAT poin penting yang membawa saya mencoba sampai aku putus asa dan menemukan komentar ini untuk memvalidasi kecurigaan saya.
DonBoitnott
64
ContentStringFormatdatang untuk menyelamatkan, misalnya: Content="{Binding Path=TargetProjects.Count}" ContentStringFormat="Projects: {0}".
astrowalker
2
Terima kasih Casper, pahlawan sejati untuk memposting info itu.
DaWiseguy
5
untuk header GridViewColumn, gunakanHeaderStringFormat="{}{0} For Report"
Felix
2
Jika Anda menggunakan data waktu desain, tampaknya Anda perlu membangun kembali proyek setelah mengedit ContentStringFormat untuk mendapatkan perubahan yang akan direfleksikan di desainer, sedangkan StringFormat seperti yang digunakan pada kotak teks akan memperbarui desainer secara realtime.
Richard Moore
-8

Di xaml

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

Dalam ViewModelhal ini, pengaturan nilai juga berfungsi:

 public string CelsiusTemp
        {
            get { return string.Format("{0}°C", _CelsiusTemp); }
            set
            {
                value = value.Replace("°C", "");
              _CelsiusTemp = value;
            }
        }
Rajesh Nath
sumber
19
Ini bertentangan dengan inti pemisahan View-Viewmodel
Askolein