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.