私は、列の小数点以下の桁数を可変にする必要があるWPFアプリケーション用のコンバーターを作成しています。ユーザーは、キーの組み合わせまたはフォームボタンを使用して、列の小数点以下の桁数を変更できます。唯一の違いは、精度が向上し、最後の桁が0の場合、精度は向上しないことです。
したがって、小数点以下3桁の精度の列の場合、次の値123.123および123.100は123.123および123.1として表示されます。
現在、これは問題なく機能しています。これを国際化しようとすると問題が発生します。私は国際化に関してさまざまなスレッドやページを読みましたが、それでもこれを正しく機能させることができないようです。誰かが私が見落としているかもしれない明らかな問題を見て、指摘することができれば幸いです。
観察されている動作は次のとおりです。データを表示するとき、コンバーターは正常に動作しており、ユーザーの地域設定に従って数値を正しくフォーマットしているようです。ユーザーがデータを更新すると、ドイツのユーザーは次の動作を経験します。
表示期待表示を入力
10001.0001.000
1.000 1 1.000
1,000 1.000 1
1,234 1.234 1,234
私のコンバーターコードは次のとおりです。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Data;
namespace xxx
{
[ValueConversion(typeof(object), typeof(string))]
public class StripDecimalsConverter : IValueConverter
{
public static readonly Regex NumberRegex = new Regex("(?<=[A-Z])(\\d+)", RegexOptions.Compiled);
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//return any integer values to 0 dp. Else apply the default decimal places to the value.
string convertedformat = parameter.ToString().ToUpper().Contains("P") ? "{0:P0}" : "{0:N0}";
string format = parameter.ToString();
int converted;
var convertedCulture = System.Globalization.CultureInfo.CurrentCulture;
if (value == null) return string.Format(culture, format, string.Empty);
else if (int.TryParse(value.ToString(), out converted))
return string.Format(convertedCulture, convertedformat, converted);
else
{
Double d;
Double.TryParse(value.ToString(), out d);
var x = (double)value;
var strippedFormat = StrippedFormat(x, format, convertedCulture);
return string.Format(convertedCulture, strippedFormat, x);
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
private string StrippedFormat(double value, string format, System.Globalization.CultureInfo culture)
{
var scaleMatch = NumberRegex.Match(format);
//What format value is being sent in by the formatter?
int requiredprecision = scaleMatch != Match.Empty ? Int32.Parse(scaleMatch.Value) : 0;
Double d = value;
int index = d.ToString().IndexOf(culture.NumberFormat.NumberDecimalSeparator);
//How many decimakl places are in the value to be formatted?
var formatlength = d.ToString().Substring(index + 1).Length;
string newformat = requiredprecision > formatlength
? (format.Contains("P") ? string.Format("{{0:P{0}}}", formatlength) : string.Format("{{0:N{0}}}", formatlength))
: (format.Contains("P")
? string.Format("{{0:P{0}}}", requiredprecision)
: string.Format("{{0:N{0}}}", requiredprecision));
return newformat;
}
}
}
コンバーターは、次のようにXAMLから呼び出されます。
StringFormat={}{0:N2},Converter={StaticResource StripDecimalsConverter},ConverterParameter=\{0:N2\}}"
私のApp.xamlには次の行も含まれています:
Thread.CurrentThread.CurrentCulture = CultureInfo.CurrentCulture;
正しい方向へのポインタが最も高く評価されます。