格式为 wpf 中没有尾随零的货币 xaml
Format as currency with no trailing zeroes in wpf xaml
假设我们有一个视图模型 属性 MyMoney
。如何在其视图 xaml 中将其格式化为没有尾随零的货币?
例如:
MyMoney = 1; //
MyMoney = 1.2 //.2
我在 xaml 中尝试了以下方法(例如 <TextBox Text="{Binding MyMoney, StringFormat=..."/>
),但它不满足所有条件:
StringFormat=C
显示货币,但也显示尾随零。
StringFormat=C0
显示货币但只显示整数。
StringFormat={}{0:0.##}
不显示尾随零但不显示为货币。
StringFormat={}{0:[=17=].##}
不显示尾随零但硬编码 $
。我们应该能够满足当前 locale/culture 的货币。
可能你会知道字符串格式的 "C" 根据你本地 machine.However 设置的 locale/culture 来回答你的问题,我建议把尾随将 属性 级别的删除代码清零,并保持 xaml 级别的字符串格式与 possible.for 一样简单,例如
在 xaml 级别:
<TextBox x:Name="TextBox_Curr" Height="50" Text="{Binding Money,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay,StringFormat={}{0:C}}" Margin="120,134,156,135"/>
在模型级别(只是原始代码):
private decimal _money;
public decimal Money
{
get { return _money; }
set {
_money = value;
_money.ToString("0.##");
NotifyPropertyChanged("Money"); }
}
它对我有用,而 运行 示例代码。
此外,如果您不想更改系统设置,您可能会选择强制文化设置。
public static class Cultures
{
public static readonly CultureInfo UnitedKingdom =
CultureInfo.GetCultureInfo("en-GB");
}
Then:
Money.ToString("C", Cultures.UnitedKingdom)
我认为您非常需要在这里使用转换器,因为需要删除尾随零。
这可能需要更多的工作但是:
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Markup;
namespace wpf_99
{
public class CurrencyFormatConverter : MarkupExtension, IValueConverter
{
// public double Multiplier { get; set; } You could pass parameters to properties.
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return CultureInfo.CurrentCulture.NumberFormat.CurrencySymbol + System.Convert.ToDecimal(value).ToString("0.##");
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string input = value.ToString();
if(!char.IsDigit(input[0]))
{
input= input.Substring(1);
}
if(input.Length == 0)
{
return 0;
}
return Decimal.Parse(input);
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
}
用法
<TextBox Text="{Binding Money,UpdateSourceTrigger=PropertyChanged, Converter={local:CurrencyFormatConverter}}"/>
首先,我想感谢@Andy 的 ,这让我使用了 IValueConverter
.
我正在发布我的解决方案,它具有以下优势:
利用 C# 的 "C" format specifier
一个。考虑负值(例如 -1 --> ()
)
b。迎合变流locale/culture
绑定到多种数据类型(decimal
、double
、int
等)。
Return DependencyProperty.UnsetValue
when ConvertBack
is unable to produce a value.
以上所有内容都遵循 StringFormat=c
在 wpf 中的行为方式(例如在 TextBox
中),除了转换器会根据需要删除尾随零。
public class CurrencyFormatConverter : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
System.Convert.ToDecimal(value).ToCurrency(culture);
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
switch (Type.GetTypeCode(targetType))
{
case TypeCode.Decimal:
return Decimal.TryParse(value.ToString(), NumberStyles.Currency, culture, out var @decimal)
? @decimal
: DependencyProperty.UnsetValue;
case TypeCode.Double:
return Double.TryParse(value.ToString(), NumberStyles.Currency, culture, out var @double)
? @double
: DependencyProperty.UnsetValue;
case TypeCode.Int16:
return Int16.TryParse(value.ToString(), NumberStyles.Currency, culture, out var int16)
? int16
: DependencyProperty.UnsetValue;
case TypeCode.Int32:
return Int32.TryParse(value.ToString(), NumberStyles.Currency, culture, out var int32)
? int32
: DependencyProperty.UnsetValue;
case TypeCode.Int64:
return Int64.TryParse(value.ToString(), NumberStyles.Currency, culture, out var int64)
? int64
: DependencyProperty.UnsetValue;
case TypeCode.Single:
return Single.TryParse(value.ToString(), NumberStyles.Currency, culture, out var single)
? single
: DependencyProperty.UnsetValue;
case TypeCode.UInt16:
return UInt16.TryParse(value.ToString(), NumberStyles.Currency, culture, out var uint16)
? uint16
: DependencyProperty.UnsetValue;
case TypeCode.UInt32:
return UInt32.TryParse(value.ToString(), NumberStyles.Currency, culture, out var uint32)
? uint32
: DependencyProperty.UnsetValue;
case TypeCode.UInt64:
return UInt64.TryParse(value.ToString(), NumberStyles.Currency, culture, out var uint64)
? uint64
: DependencyProperty.UnsetValue;
default:
throw new NotSupportedException($"Converting currency string to target type {targetType} is not supported.");
}
}
public override object ProvideValue(IServiceProvider serviceProvider) => this;
}
More info on ToCurrency
here
public static class DecimalExtensions
{
/// <summary>
/// Converts a numeric value to its equivalent currency string representation using the specified culture-specific format information.
/// </summary>
/// <param name="value">The value to be converted.</param>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <returns>The currency string representation of the value as specified by <paramref name="provider" />.</returns>
public static string ToCurrency(this decimal value, IFormatProvider provider) =>
/// Use "1" (or "-1" if value is negative)
/// as a placeholder for the actual value.
(value < 0 ? -1 : 1)
/// Format as a currency using the "C" format specifier.
.ToString("C0", provider)
/// Convert the absolute value to its string representation
/// then replace the placeholder "1".
/// We used absolute value since the negative sign
/// is already converted to its string representation
/// using the "C" format specifier.
.Replace("1", Math.Abs(value).ToString("#,0.############################", provider));
}
假设我们有一个视图模型 属性 MyMoney
。如何在其视图 xaml 中将其格式化为没有尾随零的货币?
例如:
MyMoney = 1; //
MyMoney = 1.2 //.2
我在 xaml 中尝试了以下方法(例如 <TextBox Text="{Binding MyMoney, StringFormat=..."/>
),但它不满足所有条件:
StringFormat=C
显示货币,但也显示尾随零。
StringFormat=C0
显示货币但只显示整数。
StringFormat={}{0:0.##}
不显示尾随零但不显示为货币。
StringFormat={}{0:[=17=].##}
不显示尾随零但硬编码 $
。我们应该能够满足当前 locale/culture 的货币。
可能你会知道字符串格式的 "C" 根据你本地 machine.However 设置的 locale/culture 来回答你的问题,我建议把尾随将 属性 级别的删除代码清零,并保持 xaml 级别的字符串格式与 possible.for 一样简单,例如
在 xaml 级别:
<TextBox x:Name="TextBox_Curr" Height="50" Text="{Binding Money,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay,StringFormat={}{0:C}}" Margin="120,134,156,135"/>
在模型级别(只是原始代码):
private decimal _money;
public decimal Money
{
get { return _money; }
set {
_money = value;
_money.ToString("0.##");
NotifyPropertyChanged("Money"); }
}
它对我有用,而 运行 示例代码。
此外,如果您不想更改系统设置,您可能会选择强制文化设置。
public static class Cultures
{
public static readonly CultureInfo UnitedKingdom =
CultureInfo.GetCultureInfo("en-GB");
}
Then:
Money.ToString("C", Cultures.UnitedKingdom)
我认为您非常需要在这里使用转换器,因为需要删除尾随零。 这可能需要更多的工作但是:
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Markup;
namespace wpf_99
{
public class CurrencyFormatConverter : MarkupExtension, IValueConverter
{
// public double Multiplier { get; set; } You could pass parameters to properties.
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return CultureInfo.CurrentCulture.NumberFormat.CurrencySymbol + System.Convert.ToDecimal(value).ToString("0.##");
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string input = value.ToString();
if(!char.IsDigit(input[0]))
{
input= input.Substring(1);
}
if(input.Length == 0)
{
return 0;
}
return Decimal.Parse(input);
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
}
用法
<TextBox Text="{Binding Money,UpdateSourceTrigger=PropertyChanged, Converter={local:CurrencyFormatConverter}}"/>
首先,我想感谢@Andy 的 IValueConverter
.
我正在发布我的解决方案,它具有以下优势:
利用 C# 的 "C" format specifier
一个。考虑负值(例如
-1 --> ()
)b。迎合变流locale/culture
绑定到多种数据类型(
decimal
、double
、int
等)。Return
DependencyProperty.UnsetValue
whenConvertBack
is unable to produce a value.
以上所有内容都遵循 StringFormat=c
在 wpf 中的行为方式(例如在 TextBox
中),除了转换器会根据需要删除尾随零。
public class CurrencyFormatConverter : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
System.Convert.ToDecimal(value).ToCurrency(culture);
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
switch (Type.GetTypeCode(targetType))
{
case TypeCode.Decimal:
return Decimal.TryParse(value.ToString(), NumberStyles.Currency, culture, out var @decimal)
? @decimal
: DependencyProperty.UnsetValue;
case TypeCode.Double:
return Double.TryParse(value.ToString(), NumberStyles.Currency, culture, out var @double)
? @double
: DependencyProperty.UnsetValue;
case TypeCode.Int16:
return Int16.TryParse(value.ToString(), NumberStyles.Currency, culture, out var int16)
? int16
: DependencyProperty.UnsetValue;
case TypeCode.Int32:
return Int32.TryParse(value.ToString(), NumberStyles.Currency, culture, out var int32)
? int32
: DependencyProperty.UnsetValue;
case TypeCode.Int64:
return Int64.TryParse(value.ToString(), NumberStyles.Currency, culture, out var int64)
? int64
: DependencyProperty.UnsetValue;
case TypeCode.Single:
return Single.TryParse(value.ToString(), NumberStyles.Currency, culture, out var single)
? single
: DependencyProperty.UnsetValue;
case TypeCode.UInt16:
return UInt16.TryParse(value.ToString(), NumberStyles.Currency, culture, out var uint16)
? uint16
: DependencyProperty.UnsetValue;
case TypeCode.UInt32:
return UInt32.TryParse(value.ToString(), NumberStyles.Currency, culture, out var uint32)
? uint32
: DependencyProperty.UnsetValue;
case TypeCode.UInt64:
return UInt64.TryParse(value.ToString(), NumberStyles.Currency, culture, out var uint64)
? uint64
: DependencyProperty.UnsetValue;
default:
throw new NotSupportedException($"Converting currency string to target type {targetType} is not supported.");
}
}
public override object ProvideValue(IServiceProvider serviceProvider) => this;
}
More info on ToCurrency
here
public static class DecimalExtensions
{
/// <summary>
/// Converts a numeric value to its equivalent currency string representation using the specified culture-specific format information.
/// </summary>
/// <param name="value">The value to be converted.</param>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <returns>The currency string representation of the value as specified by <paramref name="provider" />.</returns>
public static string ToCurrency(this decimal value, IFormatProvider provider) =>
/// Use "1" (or "-1" if value is negative)
/// as a placeholder for the actual value.
(value < 0 ? -1 : 1)
/// Format as a currency using the "C" format specifier.
.ToString("C0", provider)
/// Convert the absolute value to its string representation
/// then replace the placeholder "1".
/// We used absolute value since the negative sign
/// is already converted to its string representation
/// using the "C" format specifier.
.Replace("1", Math.Abs(value).ToString("#,0.############################", provider));
}