在WPF 4.0中没有正确显示双值

本文关键字:显示 WPF | 更新日期: 2023-09-27 18:20:17

我们在应用程序中有一个显示双值的文本框。该文本框连接到一个转换器,该转换器接收字符串,将其转换为双精度,并将其四舍五入到小数点后2位。然后,同一个转换器将double转换回字符串,并将其传递回视图。

现在谈谈我们面临的问题。问题是,四舍五入按预期起作用,但四舍五进不起作用。例如,如果我们在文本框中输入1.229,它会自动将其四舍五入到1.23,而如果输入1.224,它不会将其四入到1.22

我对这个问题进行了更深入的研究,发现实际的四舍五入很好,而当四舍五进的值被转移到视图时,这个过程似乎存在问题。为了进一步解释我的发现,如果我在Math.上设置了一个断点。将它返回的结果四舍五入,就是预期的结果。但是,当相同的值返回到视图时,由于某种原因,该值会发生更改,并且文本框中显示的内容不是预期的内容。

我将该项目的框架更改为4.5,发现这个问题在.NETFramework4.5中不存在,并且一切都按预期进行。但我们使用的是.NET Framework 4.0,需要一个变通方法。

转换器代码:

public class TextToNumberConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        string result = string.Empty;
        int decimalsValue = 2;
        if (parameter != null)
        {
            Int32.TryParse(parameter.ToString(), out decimalsValue);
        }
        if (!double.IsNaN(System.Convert.ToDouble(value)))
        {
            result = string.Format("{0}", Math.Round((double)value, decimalsValue, MidpointRounding.AwayFromZero));
        }
        return result;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        string inVal = (string)value;
        switch (targetType.Name)
        {
            case "Int32":
                return this.StringToInt32(inVal);
            case "Double":
                if (inVal != String.Empty &&
                inVal != "-" &&
                inVal != "-0" &&
                inVal != "-0," &&
                inVal != "-0." &&
                inVal != "-0,0" &&
                inVal != "-0.0")
                {
                    return this.StringToDouble(inVal);
                }
                else
                    return Double.NaN;
            default:
                return 0;
        }
    }
    private int StringToInt32(string inVal)
    {
        int retVal = 0;
        // remove non-integer characters
        //string regExpressionPattern = "[^0-9-]";
        //inVal = Regex.Replace(inVal, regExpressionPattern, String.Empty);
        bool result = Int32.TryParse(inVal, out retVal);
        if (true == result)
        {
            return retVal;
        }
        else
        {
            return 0;
        }
    }
    private double StringToDouble(string inVal)
    {
        double retVal = double.NaN;
        // remove non-numeric characters
        //string regExpressionPattern = "[^0-9-.,]";
        //inVal = Regex.Replace(inVal, regExpressionPattern, String.Empty);
        inVal = Regex.Replace(inVal, "[,]", CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator);
        bool result = Double.TryParse(inVal, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out retVal);
        if (true == result)
        {
            return retVal;
        }
        else
        {
            return double.NaN;
        }
    }
}

视图模型:

public class MainWindow_ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    private RxData _currentRxData_right;
    public RxData CurrentRxData_right
    {
        get
        {
            if (_currentRxData_right == null)
                _currentRxData_right = new RxData();
            return _currentRxData_right;
        }
        set
        {
            _currentRxData_right = value;
            PropertyChanged(this, new PropertyChangedEventArgs("CurrentRxData_right"));
        }
    }
}

型号代码:

public class RxData
{
   public double Sphere { get; set; }
}

数据输入文本框:

<TextBox x:Name="txt_sph" Text="{Binding CurrentRxData_right.Sphere, Converter={StaticResource TextToNumber}, Mode=TwoWay, StringFormat='{0:F2'}, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, TargetNullValue=NULL}" ></TextBox>

在WPF 4.0中没有正确显示双值

减少0.005的老把戏就可以了:

  • 1.224-0.005=1.219==圆形=>1.22
  • 1.229-0.005=1.224==圆形=>1.23