Или, чтобы быть более ясным, как я могу отформатировать блок текста (в моем случае, чтобы он был включен во всплывающую подсказку) так, чтобы некоторые части текста происходили из связанных значений.
На простом 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?





Насколько я знаю, WPF не делает то, что вам нужно. У вас есть гораздо более мощное (хотя и более сложное) решение.
Взгляните на интерфейс IValueConverter.
MSDN Как связать здесь
РЕДАКТИРОВАТЬ
Основываясь на ответе aku и вашем утверждении, что вы не можете использовать 3.5 SP1, вот альтернатива.
Взгляните на недавнюю серию публикаций Фила Хаака о форматировании строк:
Создайте ValueConverter, поскольку он принимает формат как свойство. Затем вы должны иметь возможность привязать свой объект данных и иметь его формат на основе вашего определенного формата (используя имя свойства вместо позиции).
Вы можете использовать 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 - вы не можете привязаться к нему, но есть несколько обходных путей:
круто, не знал об этой новой функции. Вы знаете, что представляют собой пустые волнистые линии в начале строки?
{} необходимо указать WPF не рассматривать {something} как расширение разметки.
Ура, аку. К сожалению, я не нацелен на SP1, так что придется убирать его. Тем не менее, я думаю, что это самый элегантный ответ, поэтому я дал его вам.
Спасибо за ссылку на BindableRun!
Раньше я решал эту проблему, фактически разбивая 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:
И этот для информации о конвертерах:
Вы можете довольно легко представить конвертер, который принимает «значения объекта []» вместо «значения объекта» в качестве первого параметра и передает их в функцию форматирования.
увеличение количества визуальных элементов может снизить производительность, также эта разметка может работать по-другому, когда происходит переполнение текста
Спасибо за ответ. Я рассматривал подход StackPanel, но он кажется немного неуклюжим, и я надеялся на что-то лучшее. Кроме того, как говорит Аку, он не мог аккуратно завернуться. К сожалению, я не использую SP1, поэтому не могу использовать MultiBinding.
WrapPanel решит проблему упаковки вместо StackPanel.
Если вы используете 3.5 SP1, ответ от Аку - это то, что вам нужно. Если нет, вы можете использовать FormatConverter из моей библиотеки Конвертеры WPF.
Спасибо, Кент, они выглядят полезными, я проверю их сегодня. Кстати, форматирование указанной вами страницы codeplex выглядит не совсем правильно в конце примеров кода (по крайней мере, в Chrome на WinXP).
Я бы разделил на несколько текстовых блоков, привязывая каждый к StringFormat = {0: P} в привязке как таковой:
<TextBox Text = "{Binding Something, StringFormat=\{0:P\}}" />
См. Этот пост для примеров: Блог Лестера WPF на StringFormat
Checkout VS2010 - привязка из свойств включает форматирование в параметрах.
Привет Майкл. Спасибо, но я надеялся сделать что-то более декларативное в XAML, вместо того, чтобы писать тип .NET, специально удовлетворяющий моим требованиям. Его нельзя будет повторно использовать за пределами этого контекста, как можно использовать String.Format.