WPF / XAML:如何在TextBlock中使所有文本大写?

时间:2014-07-25 12:39:02

标签: wpf xaml binding textblock uppercase

我希望TextBlock中的所有字符都以大写显示

 <TextBlock Name="tbAbc"
            FontSize="12"
            TextAlignment="Center"
            Text="Channel Name"
            Foreground="{DynamicResource {x:Static r:RibbonSkinResources.RibbonGroupLabelFontColorBrushKey}}" />

字符串通过Binding获取。我不想在字典本身中将字符串设为大写。

7 个答案:

答案 0 :(得分:23)

或使用

Typography.Capitals="AllSmallCaps"

TextBlock定义中。

见这里:MSDN - Typography.Capitals

修改

这不适用于 Windows Phone 8.1 ,仅适用于Windows 8.1 ...

答案 1 :(得分:10)

实施自定义转换器。

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

然后将其作为资源包含在您的XAML中:

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

并将其添加到您的绑定中:

Converter={StaticResource StringToUpperConverter}

答案 2 :(得分:4)

如果这不是什么大不了的话,你可以使用 TextBox 代替 TextBlock

<TextBox CharacterCasing="Upper" IsReadOnly="True" />

答案 3 :(得分:4)

您可以使用这样的附加属性:

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);
            }
        }
    }
}

然后在xaml中使用将如下所示:

<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>

答案 4 :(得分:2)

我使用字符大小写值转换器:

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();
    }
}

答案 5 :(得分:2)

虽然这里已经有一个很好的使用转换器的答案,但我提供了一个替代实现来简化到单行的转换(由于空合并),并使其成为 MarkupExtension 的子类所以在 XAML 中更容易使用。

这是转换器...

using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Markup;

namespace IntuoSoft.Wpf.Converters {

    [ValueConversion(typeof(string), typeof(string))]
    public class CapitalizationConverter : MarkupExtension, IValueConverter {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            => (value as string)?.ToUpper() ?? value; // If it's a string, call ToUpper(), otherwise, pass it through as-is.

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            => throw new NotSupportedException();

        public override object ProvideValue(IServiceProvider serviceProvider) => this;
    }
}

以下是您如何使用它(注意:这假设上述命名空间在您的 XAML 中以 is 为前缀):

<TextBlock Text={Binding SomeValue, Converter={is:CapitalizationConverter}}" />

因为它是一个 MarkupExtension 子类,所以您可以在需要的地方/时间简单地使用它。无需先在资源中定义。

答案 6 :(得分:-1)

将文本转换为大写的Converter怎么样?这样原始文本保持不变。

How to use IValueConverter in Binding of WPF