WPF StringFormat для содержимого меток - PullRequest
63 голосов
/ 17 ноября 2010

Я хочу отформатировать привязку строки как Amount is X, где X - это свойство, привязанное к метке.

Я видел много примеров, но следующее не работает:

<Label Content="{Binding Path=MaxLevelofInvestment, 
   StringFormat='Amount is {0}'}" />

Я также пробовал эти комбинации:

StringFormat=Amount is {0}
StringFormat='Amount is {}{0}'
StringFormat='Amount is \{0\}'

Я даже пытался изменить тип данных свойства привязки на int, string и double. Ничто не похоже на работу. Это очень распространенный вариант использования, но, похоже, он не поддерживается.

Ответы [ 5 ]

169 голосов
/ 18 ноября 2010

Причина, по которой это не работает, состоит в том, что свойство Label.Content имеет тип Object, а Binding.StringFormat используется только при привязке к свойству типа String.

Происходит следующее:

  1. Binding упаковывает ваше значение MaxLevelOfInvestment и сохраняет его в свойстве Label.Content как десятичное значение в штучной упаковке.
  2. Элемент управления Label имеет шаблон, который включает ContentPresenter.
  3. Поскольку ContentTemplate не задано, ContentPresenter ищет DataTemplate, определенный для типа Decimal.Когда он не находит ничего, он использует шаблон по умолчанию.
  4. Шаблон по умолчанию, используемый ContentPresenter, представляет строки с использованием свойства ContentStringFormat метки.

Возможны два решения:

  • Использовать Label.ContentStringFormat вместо Binding.StringFormat или
  • Использовать свойство String, например TextBlock.Text вместо Label.Content

Вот как использовать Label.ContentStringFormat:

<Label Content="{Binding Path=MaxLevelofInvestment}" ContentStringFormat="Amount is {0}" />

Вот как использовать TextBlock:

<TextBlock Text="{Binding Path=MaxLevelofInvestment, StringFormat='Amount is {0}'}" />

Примечание. Для простоты в приведенном выше объяснении я пропустил одну деталь: ContentPresenter фактически использует свои собственные свойства Template и StringFormat, но во время загрузки они автоматически привязываются к шаблону к ContentTemplate и ContentStringFormat свойствам Label, поэтому кажется, что ContentPresenterфактически используя свойства Label.

5 голосов
/ 01 марта 2016

сделать универсальный StringFormatConverter : IValueConverter. Передайте строку формата как ConverterParameter.

Label Content="{Binding Amount, Converter={...myConverter}, ConverterParameter='Amount is {0}'"

Также, сделайте StringFormatMultiConverter : IMultiValueConverter, когда вам нужно более одного объекта в строке формата, например, Completed {0} tasks out of {1}.

3 голосов
/ 17 ноября 2010

Я только что проверил, и по какой-то причине он не работает с меткой, возможно, потому, что он использует ContentPresenter для свойства Content внутри. Вместо этого вы можете использовать TextBlock, и это будет работать. Вы также можете поместить приведенный ниже фрагмент TextBlock в содержимое метки, если вам нужно наследовать стили, поведение и т. Д.

<TextBlock Text="{Binding Path=MaxLevelofInvestment, StringFormat='Amount is \{0\}'} />
1 голос
/ 18 ноября 2010

Может быть, это поможет ...

Код для вставки в XAML

1 голос
/ 17 ноября 2010

Попробуйте использовать конвертер ....

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


<Label Content="{Binding Path=MaxLevelofInvestment, Converter={StaticResource MyConverter"} />


public class MyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return String.Format("Amount is {0}", value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}
...