Jak powiązać wiele wartości z jednym TextBlock WPF?


210

Obecnie używam TextBlockponiżej, aby powiązać wartość właściwości o nazwie Name:

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

Teraz chcę powiązać inną właściwość o IDtej samej nazwie TextBlock.

Czy można powiązać dwie lub więcej wartości z tym samym TextBlock? Czy można tego dokonać za pomocą prostej konkatenacji, na przykład, Name + IDa jeśli nie, to jak inaczej można do tego podejść?

Odpowiedzi:


434

Możesz użyć w MultiBindingpołączeniu z StringFormatwłaściwością. Użycie byłoby podobne do następującego:

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

Podanie Namewartości Fooi IDwartości 1wyjściowej w TextBlock byłoby wtedy Foo + 1.

Note: że jest to obsługiwane tylko w .NET 3.5 SP1 i 3.0 SP2 lub nowszym.


5
@Preet - tak naprawdę nie jestem pewien, czy „{}” jest konieczne w tym przypadku, dołączyłem go, ponieważ został użyty w próbce MSDN. Zasadniczo jednak jest potrzebna jako sekwencja ucieczki dla parsera XAML, aby uniknąć pomyłki z rozszerzeniem znacznika Binding.
Richard McGuire,

2
Jest na to jeden efekt uboczny. Jeśli użyjesz tej metody do czegoś w rodzaju DataGridsortowania, niestety nie zadziała. Bardziej odpowiednim rozwiązaniem byłoby utworzenie właściwości tylko do odczytu w modelu z odpowiednim formatem ciągu, z którym można się wiązać. Nie trzeba dodawać, że jest to dobry sposób na szybkie sformatowanie, choć trochę zbyt szczegółowe.
Brett Ryan,

34
potrzebujesz tylko {}, gdy ciąg formatu zaczyna się od parametru {0}, nie jest potrzebny, jeśli ciąg formatu zaczyna się od tekstu. np .: „{} {0} + {1}” „Strona {0} z {1}”
Dakianth,

Nie działał w projekcie WPF .Net 4.0 Visual Studio 2017.
Sorush

@ Rozwiązanie Patrick działało dla mnie. Nie mogłem tego uruchomić. Miałem ten błądXamlParseException: 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

Wiem, że jest już późno, ale pomyślałem, że dodam jeszcze jeden sposób.

Możesz skorzystać z faktu, że właściwość Text można ustawić za pomocą „ Run s”, dzięki czemu możesz skonfigurować wiele powiązań za pomocą Run dla każdego z nich. Jest to przydatne, jeśli nie masz dostępu do MultiBinding (którego nie znalazłem podczas programowania dla Windows Phone)

<TextBlock>
  <Run Text="Name = "/>
  <Run Text="{Binding Name}"/>
  <Run Text=", Id ="/>
  <Run Text="{Binding Id}"/>
</TextBlock>

4
Jest to bardzo przydatne podejście do łączenia z kilkoma łańcuchami, które są pozyskiwane jako DynamicResource, ponieważ nie można do tego użyć MultiBinding z StringFormat.
slugster,

Właśnie tego spróbowałem. Działa, jednak każdy element (nawet geometria), który zostanie narysowany (podczas odświeżania), teraz z jakiegoś powodu miga przy każdym tiku. Idę wypróbować inną metodę.
Logan Klenner,

6
Może to być trudne, jeśli tekst musi być zlokalizowany, ponieważ kolejność jest zakodowana na stałe.
BlueM

1
Innym zastosowaniem tego podejścia jest zastosowanie innego stylu dla każdego wiązania
Hamid Naeemi

najlepsza odpowiedź na 2019 r.
Fábio BC Souza

23

Jeśli będą to tylko bloki tekstowe (a zatem wiązanie jednokierunkowe), a chcesz po prostu połączyć wartości, po prostu powiąż dwa bloki tekstowe i umieść je w poziomym panelu stosu.

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

Spowoduje to wyświetlenie tekstu (tak jak robią to wszystkie bloki Textblocks) bez konieczności dalszego kodowania. Możesz jednak nałożyć na nie niewielki margines, aby wyglądały dobrze.


11

Użyj 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;
    }
}

i w znacznikach

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

. . .

<TextBlock Text="{Binding Name, Converter={StaticResource MyConverter Parameter=ID}}" />

Tak - zostało to napisane 6 lat temu, a „Konwerter” wiąże się jako pierwszy argument z konwerterem (zwany wartością w kodzie), a identyfikator (ciąg z pytania) jako drugi argument.
Preet Sangha
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.