Використовуйте StringFormat, щоб додати рядок до WPF-прив'язки XAML


125

У мене є додаток WPF 4, який містить TextBlock, який має одностороннє прив'язування до цілого значення (в цьому випадку температура в градусах Цельсія). XAML виглядає так:

<TextBlock x:Name="textBlockTemperature">
        <Run Text="{Binding CelsiusTemp, Mode=OneWay}"/></TextBlock>

Це добре працює для відображення фактичного значення температури, але я хотів би відформатувати це значення, щоб воно включало ° C замість просто числа (30 ° C замість всього 30). Я читав про StringFormat і бачив декілька загальних прикладів на кшталт цього:

// format the bound value as a currency
<TextBlock Text="{Binding Amount, StringFormat={}{0:C}}" />

і

// preface the bound value with a string and format it as a currency
<TextBlock Text="{Binding Amount, StringFormat=Amount: {0:C}}"/>

На жаль, жоден із прикладів, які я бачив, не додав рядок до пов'язаного значення, як я намагаюся зробити. Я впевнений, що це має бути щось просте, але мені не пощастить знайти його. Хтось може мені пояснити, як це зробити?

Відповіді:


218

Ваш перший приклад - це те, що вам потрібно:

<TextBlock Text="{Binding CelsiusTemp, StringFormat={}{0}°C}" />

20
Чому формат рядка в xaml є ведучим порожнім {}?
Джонесополіс

6
@Jonesopolis Це в документах - але якщо ваш форматний рядок починається з a {, він забезпечує механізм виходу, оскільки {}вже має значення у xaml.
Рід Копсей

5
Я не бачу, де документація пояснює ведучого {}.
Ерік

5
@Eric Як і багато документації, вона смердить - вони демонструють це, але не пояснюють.
Рід Копсі

19
тут документація таємничого {}: msdn.microsoft.com/en-us/library/ms744986.aspx
Іотрій

107

Ось альтернатива, яка добре працює для читабельності, якщо у вас є Прив'язка в середині рядка або кілька прив'язок:

<TextBlock>
  <Run Text="Temperature is "/>
  <Run Text="{Binding CelsiusTemp}"/>
  <Run Text="°C"/>  
</TextBlock>

<!-- displays: 0°C (32°F)-->
<TextBlock>
  <Run Text="{Binding CelsiusTemp}"/>
  <Run Text="°C"/>
  <Run Text=" ("/>
  <Run Text="{Binding Fahrenheit}"/>
  <Run Text="°F)"/>
</TextBlock>

6
Мені подобається ця відповідь трохи краще, тому що я легко можу вставити текст із бібліотеки рядків. Звичайно, якщо ви дійсно переживаєте про інтернаціоналізацію, вам, мабуть, буде краще використовувати перетворювач, щоб порядок кількості та одиниць не було встановлено. <Run Text = "{x: Static s: UIStrings.General_FahrenheitAbbreviation}" />
Метт Бекер

1
Це чудове рішення, але я отримую додаткові пробіли у фінальному відображенні тексту, між текстовими запусками - будь-яка ідея, чому? У вашому прикладі я бачу0 °C ( 32 °F)
Конрад

Це не дуже корисно, якщо ви хочете виконати фактичне форматування рядків (тобто контролювати кількість десяткових знаків тощо).
BrainSlugs83

5
@Conrad Якщо ви не хочете пробілів між кожним прогоном, слід поставити такі прогони в один рядок наступним чином: <TextBlock> <Run Text = "{Binding CelsiusTemp}" /> <Run Text = "° C" / > <Run Text = "(" /: <Run Text = "{Binding Fahrenheit}" /> <Run Text = "° F)" /> </TextBlock>
Ladislav Ondris

94

Зауважте, що використання StringFormat у "Прив'язках" працює лише для "текстових" властивостей. Використання цього для Label.Content не буде працювати


16
Дуже важливий момент , який взяв мене спробувати його , поки я не отримав відчайдушний і знайшов цей коментар перевірити свої підозри.
DonBoitnott

64
ContentStringFormatприходить на допомогу, наприклад: Content="{Binding Path=TargetProjects.Count}" ContentStringFormat="Projects: {0}".
astrowalker

2
Дякую Каспер, справжній герой за публікацію цієї інформації.
DaWiseguy

5
для заголовків GridViewColumn, використовуйтеHeaderStringFormat="{}{0} For Report"
Felix

2
Якщо ви використовуєте дані про час проектування, вам здається, що вам потрібно відновити проект після редагування ContentStringFormat, щоб отримати зміни, що відображатимуться в дизайнері, тоді як StringFormat, як використовується у скажімо, текстове поле оновить дизайнера в режимі реального часу.
Річард Мур

-8

В xaml

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

Таким ViewModelчином, також працює такий спосіб встановлення значення:

 public string CelsiusTemp
        {
            get { return string.Format("{0}°C", _CelsiusTemp); }
            set
            {
                value = value.Replace("°C", "");
              _CelsiusTemp = value;
            }
        }

19
Це суперечить всій точці поділу View-
Viewmodel
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.