Что такое привязка данных WPF XAML, эквивалент String.Format?

Или, чтобы быть более ясным, как я могу отформатировать блок текста (в моем случае, чтобы он был включен во всплывающую подсказку) так, чтобы некоторые части текста происходили из связанных значений.

На простом C# я ​​бы использовал:

_toolTip.Text = string.Format("{1:#0}% up, {2:#0}% down",
    Environment.NewLine, percentageOne, percentage2);

Однако разметка WPF XAML для свойства Text может содержать только одну привязку. Фигурные скобки вселили в меня большие надежды, но это невозможно:

<Element>
  <Element.Tooltip>
    <!-- This won't compile -->
    <TextBlock Text = "{Binding Path=PercentageOne}% up, {Binding Path=PercentageTwo}% down"/>
  </Element.Tooltip>
</Element>

Я читал, что свойство Run.Text не является свойством зависимости и поэтому не может быть привязано.

Есть ли способ выполнить это форматирование в XAML?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
31
0
28 799
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Насколько я знаю, WPF не делает то, что вам нужно. У вас есть гораздо более мощное (хотя и более сложное) решение.

Взгляните на интерфейс IValueConverter.

MSDN Как связать здесь

РЕДАКТИРОВАТЬ

Основываясь на ответе aku и вашем утверждении, что вы не можете использовать 3.5 SP1, вот альтернатива.

Взгляните на недавнюю серию публикаций Фила Хаака о форматировании строк:

Создайте ValueConverter, поскольку он принимает формат как свойство. Затем вы должны иметь возможность привязать свой объект данных и иметь его формат на основе вашего определенного формата (используя имя свойства вместо позиции).

Привет Майкл. Спасибо, но я надеялся сделать что-то более декларативное в XAML, вместо того, чтобы писать тип .NET, специально удовлетворяющий моим требованиям. Его нельзя будет повторно использовать за пределами этого контекста, как можно использовать String.Format.

Drew Noakes 15.01.2009 18:09
Ответ принят как подходящий

Вы можете использовать MultiBinding + StringFormat (требуется WPF 3.5 SP1):

<TextBox.Text>
    <MultiBinding StringFormat = "{}{1:#0}% up, {2:#0}% down">
      <Binding Path = "PercentageOne" />
      <Binding Path = "PercentageTwo"/>
    </MultiBinding>
</TextBox.Text>

Что касается Run.Text - вы не можете привязаться к нему, но есть несколько обходных путей:

круто, не знал об этой новой функции. Вы знаете, что представляют собой пустые волнистые линии в начале строки?

Michael Meadows 15.01.2009 18:10

{} необходимо указать WPF не рассматривать {something} как расширение разметки.

aku 15.01.2009 18:14

Ура, аку. К сожалению, я не нацелен на SP1, так что придется убирать его. Тем не менее, я думаю, что это самый элегантный ответ, поэтому я дал его вам.

Drew Noakes 15.01.2009 18:53

Спасибо за ссылку на BindableRun!

John Fisher 12.07.2009 07:21

Раньше я решал эту проблему, фактически разбивая TextBlock, который есть в вашем листинге, на несколько TextBlocks. Попробуйте что-то вроде этого:

<Element>
  <Element.Tooltip>
    <StackPanel Orientation = "Horizontal">
      <TextBlock Text = "{Binding Path=PercentageOne}"/>
      <TextBlock Text = "% up, "/>
      <TextBlock Text = "{Binding Path=PercentageTwo}"/>
      <TextBlock Text = "% down"/>
    </StackPanel>
  </Element.Tooltip>
</Element>

В качестве альтернативы вы можете создать что-то вроде StringFormatConverter, который может принимать строку формата в качестве параметра и использовать MultiBinding для передачи ему параметров. См. Эту ссылку для MultiBindings:

Информация о MultiBinding

И этот для информации о конвертерах:

Информация о преобразователях

Вы можете довольно легко представить конвертер, который принимает «значения объекта []» вместо «значения объекта» в качестве первого параметра и передает их в функцию форматирования.

увеличение количества визуальных элементов может снизить производительность, также эта разметка может работать по-другому, когда происходит переполнение текста

aku 15.01.2009 18:16

Спасибо за ответ. Я рассматривал подход StackPanel, но он кажется немного неуклюжим, и я надеялся на что-то лучшее. Кроме того, как говорит Аку, он не мог аккуратно завернуться. К сожалению, я не использую SP1, поэтому не могу использовать MultiBinding.

Drew Noakes 15.01.2009 18:51

WrapPanel решит проблему упаковки вместо StackPanel.

Jon Comtois 24.04.2010 15:59

Если вы используете 3.5 SP1, ответ от Аку - это то, что вам нужно. Если нет, вы можете использовать FormatConverter из моей библиотеки Конвертеры WPF.

Спасибо, Кент, они выглядят полезными, я проверю их сегодня. Кстати, форматирование указанной вами страницы codeplex выглядит не совсем правильно в конце примеров кода (по крайней мере, в Chrome на WinXP).

Drew Noakes 16.01.2009 11:51

Я бы разделил на несколько текстовых блоков, привязывая каждый к StringFormat = {0: P} в привязке как таковой:

<TextBox Text = "{Binding Something, StringFormat=\{0:P\}}" />

См. Этот пост для примеров: Блог Лестера WPF на StringFormat

Checkout VS2010 - привязка из свойств включает форматирование в параметрах.

Другие вопросы по теме