Bagaimana cara mengikat beberapa nilai ke satu WPF TextBlock?

210

Saat ini saya menggunakan di TextBlockbawah ini untuk mengikat nilai properti bernama Name:

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

Sekarang, saya ingin mengikat properti lain dengan nama IDyang sama TextBlock.

Apakah mungkin untuk mengikat dua atau lebih nilai yang sama TextBlock? Bisakah itu dilakukan dengan penggabungan sederhana, seperti Name + IDdan, jika tidak, bagaimana lagi ini bisa didekati?

Spen D
sumber

Jawaban:

434

Anda dapat menggunakan MultiBindinggabungan dengan StringFormatproperti. Penggunaan akan menyerupai berikut ini:

<TextBlock>
    <TextBlock.Text>    
        <MultiBinding StringFormat="{}{0} + {1}">
            <Binding Path="Name" />
            <Binding Path="ID" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

Memberikan Namenilai Foodan IDnilai 1, output Anda di TextBlock akan menjadi Foo + 1.

Note: bahwa ini hanya didukung di .NET 3.5 SP1 dan 3.0 SP2 atau yang lebih baru.

Richard McGuire
sumber
5
@ Salam - Saya sebenarnya tidak yakin apakah '{}' diperlukan dalam kasus ini, saya memasukkannya karena ini digunakan pada sampel MSDN. Namun secara umum, ini diperlukan sebagai urutan keluar untuk parser XAML untuk menghindari kebingungan dengan ekstensi markup Binding.
Richard McGuire
2
Ada satu sisi yang mempengaruhi hal ini. Jika Anda menggunakan metode ini dalam sesuatu seperti DataGridperilaku penyortiran sayangnya tidak berhasil. Solusi yang lebih tepat adalah membuat properti read-only dalam model Anda dengan format string yang sesuai untuk diikat. Tak perlu dikatakan, ini adalah cara yang rapi untuk dengan cepat memformat meskipun sedikit bertele-tele.
Brett Ryan
34
Anda hanya perlu {} ketika string format dimulai dengan parameter {0}, itu tidak diperlukan jika string format dimulai dengan teks. mis: "{} {0} + {1}" "Halaman {0} dari {1}"
Dakianth
Itu tidak bekerja pada proyek WPF. Net 4.0 Visual Studio 2017.
Sorush
Solusi @ Patrick berhasil untuk saya. Saya tidak bisa membuatnya bekerja. Saya memiliki kesalahan iniXamlParseException: A 'Binding' cannot be set on the 'Path' property of type 'Binding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
Tyson Williams
127

Saya tahu ini terlambat, tetapi saya pikir saya akan menambahkan cara lain untuk melakukan ini.

Anda dapat memanfaatkan fakta bahwa properti Teks dapat diatur menggunakan " Run s", sehingga Anda dapat mengatur beberapa binding menggunakan Run untuk masing-masing. Ini berguna jika Anda tidak memiliki akses ke MultiBinding (yang saya tidak temukan ketika mengembangkan untuk Windows Phone)

<TextBlock>
  <Run Text="Name = "/>
  <Run Text="{Binding Name}"/>
  <Run Text=", Id ="/>
  <Run Text="{Binding Id}"/>
</TextBlock>
Patrick
sumber
4
Ini adalah pendekatan yang sangat berguna untuk digunakan ketika mengikat ke beberapa string yang bersumber sebagai DynamicResource karena Anda tidak dapat menggunakan MultiBinding dengan StringFormat untuk itu.
Slugster
Saya baru saja mencoba ini. Ini bekerja, namun setiap elemen (bahkan geometri) yang ditarik (saat refresh) sekarang berkedip setiap centang untuk beberapa alasan. Akan mencoba metode lain.
Logan Klenner
6
Ini bisa menjadi sulit jika teks harus dilokalkan karena urutannya adalah hardcoded.
BlueM
1
Penggunaan lain dari pendekatan ini adalah menerapkan gaya yang berbeda untuk setiap ikatan
Hamid Naeemi
jawaban terbaik untuk 2019
Fábio BC Souza
23

Jika ini hanya akan menjadi textblock (dan dengan demikian salah satu cara mengikat), dan Anda hanya ingin menggabungkan nilai, cukup ikat dua textblock dan letakkan di stackpanel horizontal.

    <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding Name}"/>
        <TextBlock Text="{Binding ID}"/>
    </StackPanel>

Itu akan menampilkan teks (yang semua Textblock lakukan) tanpa harus melakukan pengkodean lagi. Anda mungkin menempatkan sedikit margin pada mereka untuk membuatnya terlihat benar.

CodeWarrior
sumber
11

Gunakan ValueConverter

[ValueConversion(typeof(string), typeof(String))]
public class MyConverter: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return string.Format("{0}:{1}", (string) value, (string) parameter);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {

        return DependencyProperty.UnsetValue;
    }
}

dan di markup

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

. . .

<TextBlock Text="{Binding Name, Converter={StaticResource MyConverter Parameter=ID}}" />
Praha Sangha
sumber
Ya - ini ditulis 6 tahun yang lalu, dan Anda mengikat "Nama" sebagai argumen pertama ke konverter (disebut nilai dalam kode), dan ID (string dari pertanyaan) sebagai argumen kedua.
Preha Sangha