web-dev-qa-db-fra.com

Comment faire tout le texte en majuscule / majuscule?

Je veux tous les textes dans TextBlock, Label, MenuItem.Header à afficher en majuscules. Les chaînes proviennent d'un ResourceDictionary par exemple:

<TextBlock Text="{StaticResource String1}"/>
<MenuItem Header="{StaticResource MenuItemDoThisAndThat}"/>

etc. (également pour Label et d'autres contrôles)

Je ne peux pas utiliser de convertisseur de valeur car il n'y a pas de liaison. Je ne veux pas mettre les chaînes en majuscules dans le dictionnaire lui-même.

33
GG.

Vous pouvez toujours utiliser un convertisseur, il suffit de définir la valeur du texte dans la source de la liaison:

<TextBlock Text="{Binding Source={StaticResource String1},  Converter ={StaticResource myConverter}}"/>
33
Peter

Plutôt que d'utiliser un convertisseur, vous pouvez utiliser la balise CharacterCasing dans un TextBox mais dans votre cas, cela ne fonctionne pas sur un TextBlock.

<TextBox CharacterCasing="Upper" Text="{StaticResource String1}" />
31
scrat789

Je pense que cela fonctionnera pour vous

<TextBlock Text='{StaticResource String1}'Typography.Capitals="AllSmallCaps"/>

Pour les énumérations de capitales de police https://msdn.Microsoft.com/en-us/library/system.windows.fontcapitals (v = vs.110) .aspx

23
Alias Varghese

Pour compléter la réponse de Peter (ma modification a été rejetée), vous pouvez utiliser un convertisseur comme celui-ci:

C #:

public class CaseConverter : IValueConverter
{    
    public CharacterCasing Case { get; set; }

    public CaseConverter()
    {
        Case = CharacterCasing.Upper;
    }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var str = value as string;
        if (str != null)
        {
            switch (Case)
            {
                case CharacterCasing.Lower:
                    return str.ToLower();
                case CharacterCasing.Normal:
                    return str;
                case CharacterCasing.Upper:
                    return str.ToUpper();
                default:
                    return str;
            }
        }
        return string.Empty;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

XAML:

<TextBlock Text="{Binding Source={StaticResource String1}, Converter ={StaticResource myCaseConverter}}"/>
12
Max

J'ai créé une propriété attachée et un convertisseur pour cela. Vous avez probablement déjà le convertisseur, alors remplacez ma référence à CaseConverter par l'implémentation que vous avez.

La propriété jointe est juste un booléen que vous définissez si vous voulez qu'elle soit en majuscule (vous pouvez évidemment l'étendre pour qu'elle soit à la place un énumérable pour une sélection de styles). Lorsque la propriété change, elle lie à nouveau la propriété Text de TextBlock selon les besoins, en ajoutant le convertisseur.

Un peu plus de travail peut être nécessaire lorsque la propriété est déjà liée - ma solution suppose qu'il s'agit d'une simple liaison de chemin. Mais il peut également être nécessaire de dupliquer la source, etc. Cependant, je pense que cet exemple est suffisant pour faire passer mon message.

Voici la propriété jointe:

public static bool GetUppercase(DependencyObject obj)
    {
        return (bool)obj.GetValue(UppercaseProperty);
    }

    public static void SetUppercase(DependencyObject obj, bool value)
    {
        obj.SetValue(UppercaseProperty, value);
    }

    // Using a DependencyProperty as the backing store for Uppercase.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty UppercaseProperty =
        DependencyProperty.RegisterAttached("Uppercase", typeof(bool), typeof(TextHelper), new PropertyMetadata(false, OnUppercaseChanged));

    private static void OnUppercaseChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        TextBlock txt = d as TextBlock;

        if (txt == null) return;

        var val = (bool)e.NewValue;

        if (val)
        {
            // rebind the text using converter
            // if already bound, use it as source

            var original = txt.GetBindingExpression(TextBlock.TextProperty);

            var b = new Binding();

            if (original != null)
            {
                b.Path = original.ParentBinding.Path;
            }
            else
            {
                b.Source = txt.Text;
            }

            b.Converter = new CaseConverter() { Case = CharacterCasing.Upper };


            txt.SetBinding(TextBlock.TextProperty, b);
        }
    }
8
Lauren

Cela ne répond pas strictement à la question mais fournit une astuce pour provoquer le même effet.

Je crois que beaucoup de gens qui trouvent leur chemin ici cherchent comment faire cela avec un style. TextBlock est un peu délicat ici car ce n'est pas un Control mais un FrameworkElement et donc vous ne pouvez pas définir un Template pour faire l'astuce.

La nécessité d'utiliser tout le texte en majuscules est très probable pour les en-têtes ou quelque chose comme ça où l'utilisation de Label est justifiée. Ma solution était:

<!-- Examples of CaseConverter can be found in other answers -->

<ControlTemplate x:Key="UppercaseLabelTemplate" TargetType="{x:Type Label}">
    <TextBlock Text="{TemplateBinding Content, Converter={StaticResource CaseConverter}}" />
</ControlTemplate>

<Style x:Key="UppercaseHeadingStyle"
       TargetType="{x:Type Label}">
    <Setter Property="FontSize" Value="20" />
    <Setter Property="FontWeight" Value="Bold" />
    <Setter Property="Template" Value="{StaticResource UppercaseLabelTemplate}" />
</Style>

<!-- Usage: -->
<Label Content="Header" Style="{StaticResource UppercaseHeadingStyle}" />

Notez que cela désactive certains des comportements par défaut de Label, et ne fonctionne que pour le texte, donc je ne définirais pas cela par défaut (personne ne veut probablement toutes les étiquettes en majuscules de toute façon). Et bien sûr, vous devez utiliser Label au lieu de TextBlock lorsque vous avez besoin de ce style. De plus, je ne l'utiliserais pas dans d'autres modèles, mais uniquement comme style de sujet.

2
Ahe