WPF/XAML: How to make all text upper case in TextBlock?

后端 未结 6 774
青春惊慌失措
青春惊慌失措 2021-02-13 17:59

I want all characters in a TextBlock to be displayed in uppercase

 

        
相关标签:
6条回答
  • 2021-02-13 18:16

    Implement a custom converter.

    using System.Globalization;
    using System.Windows.Data;
    // ...
    public class StringToUpperConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null && value is string )
            {
                return ((string)value).ToUpper();
            }
    
            return value;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }
    }
    

    Then include that in your XAML as a resource:

    <local:StringToUpperConverter  x:Key="StringToUpperConverter"/>
    

    And add it to your binding:

    Converter={StaticResource StringToUpperConverter}
    
    0 讨论(0)
  • 2021-02-13 18:23

    You can use an attached property like this:

    public static class TextBlock
    {
        public static readonly DependencyProperty CharacterCasingProperty = DependencyProperty.RegisterAttached(
            "CharacterCasing",
            typeof(CharacterCasing),
            typeof(TextBlock),
            new FrameworkPropertyMetadata(
                CharacterCasing.Normal,
                FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.NotDataBindable,
                OnCharacterCasingChanged));
    
        private static readonly DependencyProperty TextProxyProperty = DependencyProperty.RegisterAttached(
            "TextProxy",
            typeof(string),
            typeof(TextBlock),
            new PropertyMetadata(default(string), OnTextProxyChanged));
    
        private static readonly PropertyPath TextPropertyPath = new PropertyPath("Text");
    
    
        public static void SetCharacterCasing(DependencyObject element, CharacterCasing value)
        {
            element.SetValue(CharacterCasingProperty, value);
        }
    
        public static CharacterCasing GetCharacterCasing(DependencyObject element)
        {
            return (CharacterCasing)element.GetValue(CharacterCasingProperty);
        }
    
        private static void OnCharacterCasingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is System.Windows.Controls.TextBlock textBlock)
            {
                if (BindingOperations.GetBinding(textBlock, TextProxyProperty) == null)
                {
                    BindingOperations.SetBinding(
                        textBlock,
                        TextProxyProperty,
                        new Binding
                        {
                            Path = TextPropertyPath,
                            RelativeSource = RelativeSource.Self,
                            Mode = BindingMode.OneWay,
                        });
                }
            }
        }
    
        private static void OnTextProxyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            d.SetCurrentValue(System.Windows.Controls.TextBlock.TextProperty, Format((string)e.NewValue, GetCharacterCasing(d)));
    
            string Format(string text, CharacterCasing casing)
            {
                if (string.IsNullOrEmpty(text))
                {
                    return text;
                }
    
                switch (casing)
                {
                    case CharacterCasing.Normal:
                        return text;
                    case CharacterCasing.Lower:
                        return text.ToLower();
                    case CharacterCasing.Upper:
                        return text.ToUpper();
                    default:
                        throw new ArgumentOutOfRangeException(nameof(casing), casing, null);
                }
            }
        }
    }
    

    Then usage in xaml will look like:

    <StackPanel>
        <TextBox x:Name="TextBox" Text="abc" />
        <TextBlock local:TextBlock.CharacterCasing="Upper" Text="abc" />
        <TextBlock local:TextBlock.CharacterCasing="Upper" Text="{Binding ElementName=TextBox, Path=Text}" />
        <Button local:TextBlock.CharacterCasing="Upper" Content="abc" />
        <Button local:TextBlock.CharacterCasing="Upper" Content="{Binding ElementName=TextBox, Path=Text}" />
    </StackPanel>
    
    0 讨论(0)
  • 2021-02-13 18:27

    If it's not a big deal you could use TextBox instead of TextBlock like this:

    <TextBox CharacterCasing="Upper" IsReadOnly="True" />
    
    0 讨论(0)
  • 2021-02-13 18:29

    How about a Converter that converts your text to uppercase. This way you original text stays unchanged.

    How to use IValueConverter in Binding of WPF

    0 讨论(0)
  • 2021-02-13 18:35

    I use a character casing value converter:

    class CharacterCasingConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var s = value as string;
            if (s == null)
                return value;
    
            CharacterCasing casing;
            if (!Enum.TryParse(parameter as string, out casing))
                casing = CharacterCasing.Upper;
    
            switch (casing)
            {
                case CharacterCasing.Lower:
                    return s.ToLower(culture);
                case CharacterCasing.Upper:
                    return s.ToUpper(culture);
                default:
                    return s;
            }
        }
    
        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
    
    0 讨论(0)
  • 2021-02-13 18:40

    Or use

    Typography.Capitals="AllSmallCaps"
    

    in your TextBlock definition.

    See here: MSDN - Typography.Capitals

    EDIT:

    This does not work in Windows Phone 8.1, only in Windows 8.1 ...

    0 讨论(0)
提交回复
热议问题