Як прив’язати кілька значень до одного текстового блоку WPF?


210

Наразі я використовую TextBlockнижче, щоб прив’язати значення властивості з назвою Name:

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

Тепер я хочу прив’язати ще одне властивість, назване IDдо того ж TextBlock.

Чи можна прив’язати два і більше значень до однакових TextBlock? Чи можна це зробити за допомогою простого конкатенації, як, Name + IDа якщо ні, то як ще можна підходити до цього?

Відповіді:


434

Ви можете використовувати MultiBindingкомбінований із StringFormatвласністю. Використання нагадує таке:

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

Даючи Nameзначення Fooта IDзначення 1, то ваш вихід у TextBlock буде таким Foo + 1.

Note: що це підтримується лише в .NET 3.5 SP1 та 3.0 SP2 або новіших версіях.


5
@Preet - Я фактично не впевнений, чи потрібен '{}' в цьому випадку, я включив його, оскільки він використовувався на вибірці MSDN. Однак, як правило, вона потрібна як послідовність виходу для аналізатора XAML, щоб уникнути плутанини з розширенням розмітки Binding.
Річард Макгуайер

2
У цьому є один побічний вплив. Якщо ви використовуєте цей метод у чомусь на зразок DataGridсортування, на жаль, не працює. Більш підходящим рішенням було б створити властивість лише для читання у вашій моделі із відповідним рядковим форматом, для якого слід пов'язувати. Потрібно говорити, що це акуратний спосіб швидкого форматування, хоч і невеликого багатослівного.
Бретт Райан

34
вам просто потрібно {}, коли рядок формату починається з параметра {0}, він не потрібен, якщо рядок формату починається з тексту. наприклад: "{} {0} + {1}" "Сторінка {0} з {1}"
Дакіант

Він не працював над проектом WPF. Net 4.0 Visual Studio 2017.
Соруш,

@ Рішення Патріка працювало на мене. Я не міг змусити це працювати. У мене була така помилкаXamlParseException: A 'Binding' cannot be set on the 'Path' property of type 'Binding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
Тайсон Вільямс

127

Я знаю, що це шлях пізно, але я думав, що додам ще один спосіб зробити це.

Ви можете скористатися тим, що властивість Text можна встановити за допомогою " Run s", тому ви можете встановити кілька прив'язок, використовуючи Run для кожного. Це корисно, якщо у вас немає доступу до програми MultiBinding (яку я не знайшов при розробці для Windows Phone)

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

4
Це дуже зручний підхід для використання при прив'язці до декількох рядків, які створюються як DynamicResource, оскільки для цього ви не можете використовувати MultiBinding із StringFormat.
slugster

Я просто спробував це. Він працює, однак кожен елемент (навіть геометрія), який буде намальований (оновлений), тепер миготить кожну галочку з якоїсь причини. Збираюся спробувати інший метод.
Логан Кленнер

6
Це може стати складним, якщо текст потрібно локалізувати, оскільки замовлення жорстко закодовано.
BlueM

1
Іншим використанням цього підходу є застосування різного стилю для кожної палітурки
Хамід Наемі

найкраща відповідь на 2019 рік
Fábio BC Souza

23

Якщо це просто текстові блоки (і, таким чином, в одну сторону прив'язки), і ви просто хочете об'єднати значення, просто зв’яжіть два текстові блоки і покладіть їх у горизонтальну стекпанель.

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

Це відобразить текст (що це все Textblocks роблять), не потребуючи більше кодування. Ви можете поставити їм невеликий запас, щоб вони виглядали правильно.


11

Використовуйте 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;
    }
}

і в розмітці

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

. . .

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

Так - це було написано 6 років тому, і ви прив'язуєте "Ім'я" як перший аргумент до перетворювача (називається значенням у коді), а ID (рядок із запитання) як другий аргумент.
Преет Сангха
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.