You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让NumberBox显示并返回Decimal值?绑定DecimalFormatter报错求解

NumberBox绑定DecimalFormatter抛出异常的解决方法

问题场景

在ListView中使用NumberBox,绑定集合内的Decimal类型属性,要求UI以Decimal格式显示值,且返回值为Decimal而非Double。在ViewModel中初始化DecimalFormatter并绑定到NumberBox的NumberFormatter属性时,抛出异常:Failed to assign the property Microsoft.UI.Xaml.Controls.NumberBox.NumberFormatter。

相关代码:

XAML代码

<NumberBox x:Name="nbFeedCost"
    Grid.Column="30"
    IsWrapEnabled="true"
    NumberFormatter="{Binding DataContext.Formatter, ElementName=ngLot}"
    Style="{StaticResource NumberBoxRightAlignStyle}"
    Value="{Binding FeedCost, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

ViewModel代码

DecimalFormatter Formatter = new DecimalFormatter();

原因分析

NumberBox.NumberFormatter属性要求的是INumberFormatter2接口类型,而DecimalFormatter属于Windows.Globalization.NumberFormatting命名空间,它实现的是INumberFormatter和INumberParser,并不兼容INumberFormatter2,直接绑定会导致类型不匹配的异常。

解决方案

方法1:自定义兼容的格式化器

实现一个继承INumberFormatter2的类,内部用DecimalFormatter处理格式化逻辑:

using Windows.Globalization.NumberFormatting;

public class NumberBoxDecimalFormatter : INumberFormatter2
{
    private readonly DecimalFormatter _decimalFormatter;

    public NumberBoxDecimalFormatter()
    {
        _decimalFormatter = new DecimalFormatter();
        // 可按需设置小数位数等格式
        _decimalFormatter.FractionDigits = 2;
    }

    public string FormatDouble(double value)
    {
        return _decimalFormatter.Format((decimal)value);
    }

    public string FormatInt(long value)
    {
        return _decimalFormatter.Format((decimal)value);
    }

    public string FormatUInt(ulong value)
    {
        return _decimalFormatter.Format((decimal)value);
    }

    public string FormatDecimal(decimal value)
    {
        return _decimalFormatter.Format(value);
    }
}

然后在ViewModel中初始化这个自定义格式化器:

public INumberFormatter2 Formatter { get; } = new NumberBoxDecimalFormatter();

方法2:用值转换器+内置格式属性

如果不需要复杂区域化格式,可放弃绑定NumberFormatter,改用值转换器处理Decimal与Double的类型转换,同时用NumberBox的内置属性控制显示格式:

  1. 实现值转换器:
public class DecimalToDoubleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return value is decimal decimalValue ? (double)decimalValue : 0.0;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return value is double doubleValue ? (decimal)doubleValue : 0m;
    }
}
  1. 在XAML中引用并绑定:
<Page.Resources>
    <local:DecimalToDoubleConverter x:Key="DecimalToDoubleConverter" />
</Page.Resources>

<NumberBox x:Name="nbFeedCost"
    Grid.Column="30"
    IsWrapEnabled="true"
    MinimumNumberDigits="2"
    MaximumNumberDigits="2"
    Style="{StaticResource NumberBoxRightAlignStyle}"
    Value="{Binding FeedCost, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource DecimalToDoubleConverter}}" />

关键注意点

  • NumberBox的Value属性默认是double类型,双向绑定Decimal类型必须使用值转换器,否则会出现绑定错误。
  • 自定义格式化器必须实现INumberFormatter2接口,确保与NumberBox的属性类型兼容。

内容的提问来源于stack exchange,提问作者SANJEEV PRATAP Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 07:05:14