Home > Net >  WPF Decimal Custom Format without Rounding
WPF Decimal Custom Format without Rounding

Time:02-01

MS documentation says it this is not possible... Hoping I missed something in the docs.

want to format decimal number as: -9,999.000 using StringFormat={}{0:#,0.000} works, but this "rounds" the input where as I want to "truncate" the input.

To test, in WPF form applied this string format to a TextBox bound to a decimal property.

When I enter test values, the actual formatted value doesnt match the expected formatted value as the format string automatically "rounds" the decimal values.

Enter     Expected     Actual
1111.999  1,111.999    1,111.999
1111.9999 1,111.999    1,112,000

MS documentation clearly states that "0" placeholders will always round. great, but I dont want that behavior.

Question: is there a format string to show 3 decimal places (with trailing zeros) without using the "0"? or is there a format string that truncates at 3 decimal places instead of rounding at 3 decimal places?

I did try StringFormat={}{0:#,0.###} but that removes trailing zeros. (and also StringFormat={}{F3}).

Enter     Expected     Actual
1111.100  1,111.100    1,111.1

closest solution I could find has been [https://stackoverflow.com/questions/16914224/wpf-textbox-to-enter-decimal-values] but none of the answers really deal with the rounding versus truncate.

UPDATE

xaml code where StringFormat is used.

 <TextBox Text="{Binding 
     TemplateNumber,
     StringFormat={}{0:F3},
     ValidatesOnDataErrors=True, 
     NotifyOnValidationError=True, 
     UpdateSourceTrigger=PropertyChanged, 
     Delay=500}"
     />

CodePudding user response:

The .Net custom numerical formatting is set in stone, there's nothing you can do about it. Specifically:

The "00" specifier causes the value to be rounded to the nearest digit preceding the decimal, where rounding away from zero is always used

If you want a different kind of rounding to be applied, you can use Math.Round, which takes an argument specifying the kind of rounding you'd like (in your case, it looks like MidpointRounding.ToZero or MidpointRounding.ToNegativeInfinity, hard to tell).

CodePudding user response:

You can use IValueConverter for example:

class DecimalConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {                        
            return string.Format("{0:F3}", value);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (decimal.TryParse(value?.ToString().Replace(" ", ""), out decimal num1))
                return num1;
            return null;
        }
    }

Add it to your control

<UserControl.Resources>
    <local:DecimalConverter x:Key="MyDecimalConverter"/>
</UserControl.Resources>

Use in textbox

<TextBox Text={Binding ...., Converter={StaticResource MyDecimalConverter}}/>
  •  Tags:  
  • Related