如何在WPF中使用我的函数进行TextFormatting?

时间:2018-02-20 21:15:18

标签: .net wpf

我写了IFormatProviderICustomFormatter,但我怎样才能在xaml中使用它们?

有办法注册ICustomFormatter吗? 理想情况下,我的ICustomFormatter应该替换默认的货币格式化程序。

例如:

TextBlock Text="{Binding Value,  StringFormat='{}{0:0.000 000}'}" />

如何在StringFormat设置我的功能?

2 个答案:

答案 0 :(得分:0)

Okey,IValueConverter非常方便。

class PriceToString : IValueConverter {

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
        var number = System.Convert.ToDecimal( value );
        var integer = Math.Truncate( number );
        var fraction = number - integer;

        return integer.ToString( "N0" ) +
            NumberFormatInfo.CurrentInfo.NumberDecimalSeparator +
            Split( fraction, 6, NumberFormatInfo.CurrentInfo.NumberGroupSeparator );
    }


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



    private static string Split(decimal fraction, int precision, string separator) {
        var src = fraction.ToString( "F" + precision ).Substring( 2 );

        var result = new StringBuilder();
        for (int i = 0; i < src.Length; i++) {
            if (i % 3 == 0 && i != 0) result.Append( separator );
            result.Append( src[i] );
        }
        return result.ToString();
    }

}

<TextBlock Text="{Binding Value,  Converter='{StaticResource PriceToString}'}"/>

答案 1 :(得分:0)

更简单的方法是覆盖当前文化的数字格式设置,以使用' '作为组分隔符,然后让内置格式化程序为您完成工作:

public class CurrencyConverter : IValueConverter {
    [ThreadStatic] private static StringBuilder scratch;
    [ThreadStatic] private static NumberFormatInfo format;

    private StringBuilder Scratch => (scratch ?? (scratch = new StringBuilder()));

    private NumberFormatInfo Format {
        get {
            if (format != null)
                return format;

            var modifiedCulture = new CultureInfo(
                CultureInfo.CurrentUICulture.IetfLanguageTag,
                useUserOverride: true);

            modifiedCulture.NumberFormat.NumberGroupSeparator = " ";
            format = modifiedCulture.NumberFormat;

            return format;
        }
    }

    public object Convert(object value, Type t, object p, CultureInfo c) {
        if (value is IFormattable f)
            return f.ToString("#,0.000 000", Format);

        return Scratch.Clear()
                      .AppendFormat(Format, "{0:#,0.000 000}", value)
                      .ToString();
    }

    object IValueConverter.ConvertBack(object value, Type t, object p, CultureInfo c) {
        return DependencyProperty.UnsetValue;
    }
}

这也应该产生更少的垃圾并且效率更高。

示例结果:

> new CurrencyConverter().Convert(1234567890.1234567890m, typeof(string), null, null)
"1 234 567 890.123 457"