web-dev-qa-db-fra.com

WPF StringFormat sur le contenu de l'étiquette

Je souhaite formater ma liaison de chaîne en tant que Amount is XX est une propriété liée à une étiquette.

J'ai vu de nombreux exemples, mais ce qui suit ne fonctionne pas:

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

J'ai aussi essayé ces combinaisons:

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

J'ai même essayé de modifier le type de données de la propriété de liaison en int, stringet double. Rien ne semble fonctionner. C’est un cas d’utilisation très courant mais qui ne semble pas être pris en charge.

60
Everything Matters

Cela ne fonctionne pas parce que la propriété Label.Content est de type Object et que Binding.StringFormat n'est utilisé que lors de la liaison à une propriété de type String.

Ce qui se passe c'est:

  1. La Binding met en boîte votre valeur MaxLevelOfInvestment et la stocke dans la propriété Label.Content sous forme de valeur décimale encadrée.
  2. Le contrôle Label a un modèle qui inclut un ContentPresenter.
  3. Puisque ContentTemplate n'est pas défini, ContentPresenter recherche un DataTemplate défini pour le type Decimal. Lorsqu'il n'en trouve aucun, il utilise un modèle par défaut.
  4. Le modèle par défaut utilisé par ContentPresenter présente les chaînes en utilisant la propriété ContentStringFormat de l'étiquette.

Deux solutions sont possibles:

  • Utilisez Label.ContentStringFormat au lieu de Binding.StringFormat, ou
  • Utilisez une propriété String telle que TextBlock.Text au lieu de Label.Content

Voici comment utiliser Label.ContentStringFormat:

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

Voici comment utiliser un TextBlock:

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

Remarque: par souci de simplicité, j’ai omis un détail dans l’explication ci-dessus: La ContentPresenter utilise ses propres propriétés Template et StringFormat, mais lors du chargement, elles sont automatiquement liées au modèle par la ContentTemplate et ContentStringFormat propriétés de la Label, il semble donc que la ContentPresenter utilise réellement les propriétés de la Label.

175
Ray Burns

Je viens de vérifier et pour une raison quelconque, cela ne fonctionne pas avec Label, probablement parce qu'il utilise un ContentPresenter pour la propriété Content en interne. Vous pouvez utiliser un TextBlock à la place et cela fonctionnera. Vous pouvez également insérer l'extrait TextBlock ci-dessous dans le contenu d'une étiquette si vous devez hériter du style, du comportement, etc.

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

Créez un StringFormatConverter : IValueConverter universel. Passez votre chaîne de format en tant que ConverterParameter.

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

Faites aussi StringFormatMultiConverter : IMultiValueConverter lorsque vous avez besoin de plusieurs objets dans une chaîne de format, par exemple Completed {0} tasks out of {1}.

3
Michael Agroskin

Essayez d'utiliser un convertisseur ....

<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;
    }
}
1
Gabe

Peut-être que ça va aider ...

Code d'intégration dans XAML

0
strattonn