Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NumericUpDown control changes #5981

Merged
merged 10 commits into from
Jul 11, 2021

Conversation

puppetsw
Copy link
Contributor

@puppetsw puppetsw commented May 27, 2021

What does the pull request do?

Attempts to issue #5318 fix by adding a property for decimal places to the control.

What is the current behavior?

When the NumericUpDown control is at a value of 5.6 and Increment is 0.01, if adjusted up, it will appear as 0.570000000000000001 instead of 0.57

What is the updated/expected behavior with this PR?

The value should be 0.57

How was the solution implemented (if it's not obvious)?

Changing the backing type for NumericUpDown to decimal breaks contracts.

Checklist

Breaking changes

Changing the backing type for NumericUpDown to decimal breaks contracts.

Obsoletions / Deprecations

CultureInfo property is obsolete @AvaloniaUI/core
Users should use NumberFormat instead.

Fixed issues

Fixes #5318

@maxkatz6
Copy link
Member

Thanks for the contribution!
Am I right, that with this implementation if won't apply rounding for values that were manually inputed or came from binding? So, everything but increment/decrement.
I had quick look, and it seems that ConvertTextToValue method suits well to have rounding:

@danwalmsley
Copy link
Member

@maxkatz6 probably we have something in MathUtils class that can deal with this kind of stuff?

@maxkatz6
Copy link
Member

@danwalmsley I don't see anything that can help us in https://github.com/AvaloniaUI/Avalonia/blob/master/src/Avalonia.Base/Utilities/MathUtilities.cs

But I am not sure, do we need to Round here or Truncate?

@robloo
Copy link
Contributor

robloo commented May 27, 2021

Internally, the backing type should probably be decimal. Then Value is just a double conversion of the internal decimal for backwards compatiblity. A new DecimalValue should be added. The only reason this wasn't done in the NumberBox in WinUI is because C++ has no decimal type.

Note: Switching to decimal is especially important for currency input scenarios where precision is mandatory in the math. This shouldn't just be "hidden" using rounding techniques.

@puppetsw
Copy link
Contributor Author

puppetsw commented May 27, 2021

Thanks for the contribution!
Am I right, that with this implementation if won't apply rounding for values that were manually inputed or came from binding? So, everything but increment/decrement.
I had quick look, and it seems that ConvertTextToValue method suits well to have rounding:

Yes, that was how I approached it. But it makes more sense to change the backing type to decimal considering currency input.

I'm happy to make the changes for decimal backing type. or Adding a new DecimalValue.

Sorry I'm new to this, should I close out this PR?

@robloo
Copy link
Contributor

robloo commented May 27, 2021

A few other comments:

  • If it was me, I wouldn't close the PR. I would just revert commits and add changes as needed. It's good to keep all the discussion like this in one place.
  • Generally, rounding should be handled by the number formatting itself. I would never add a DecimalPlaces property like some old controls might have. Instead, the ToString and parsing methods should be using a NumberFormatInfo that can be defined by the developer as a property. Otherwise, it should default to the current UI culture one. This is an oversimplification of a much larger discussion that was had over on the WinUI repo (still unresolved). Bottom line, Hex, Currency, Decimal, Integer, etc formats all need to be easily supported. This at first seems out of scope for this discussion, but is very much related to decimal place precision as it relates to overall formatting.

Edit

It seems NumericUpDown has most of the pieces for doing formatting correctly already: CultureInfo and NumberStyles are already properties. The issue is CultureInfo should instead be a NumberFormatInfo. Doing this means you can then customize the NumberFormatInfo controlling the decimal places: https://docs.microsoft.com/en-us/dotnet/api/system.globalization.numberformatinfo.numberdecimaldigits?view=net-5.0. It would be possible to add a new NumberFormat property and use that in code. Then keep CultureInfo for backwards compatiblity but use it to directly set the NumberFormat property.

The decimal backing type change plus adding the NumberFormat (type NumberFormatInfo) property would cover all bases here I think.

…d ThrowCannotBeGreaterThanException to accept generics as it displays the values only.
@maxkatz6
Copy link
Member

@puppetsw technically switching from double to decimal is a breaking changes, that's why build is failing. You need to follow this tutorial to allow that https://stu.dev/check-for-breaking-changes-with-apicompat/ .

@puppetsw puppetsw changed the title Added DecimalPlaces property to NumericUpDown control NumericUpDown control changes May 28, 2021
@puppetsw
Copy link
Contributor Author

I've made type changes to the NumericUpDown class and event class. Added a NumberFormat property and have also set it through the CultureInfo to keep backwards compatibility. Marked CultureInfo as Obsolete.

I also added a new Clamp method to the MathUtilities.

@robloo
Copy link
Contributor

robloo commented May 29, 2021

Marked CultureInfo as Obsolete.

Core team doesn't really like anyone marking things as obsolete unless you run in past them first. @danwalmsley will need to buy in on this.

/// <param name="min">The minimum value.</param>
/// <param name="max">The maximum value.</param>
/// <returns>The clamped value.</returns>
public static decimal Clamp(decimal val, decimal min, decimal max)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not available in netstandard 2.0

@grokys
Copy link
Member

grokys commented Jul 6, 2021

I've not really been following this PR - are we agreed that it's a good idea to break the API and change the values from double to decimal?

@maxkatz6
Copy link
Member

maxkatz6 commented Jul 6, 2021

@grokys personally I agree with that. Also it seems to be binary breaking change only, since both xaml and c# implicitly convert from decimal to double and in other way.

@grokys
Copy link
Member

grokys commented Jul 7, 2021

Ok, I'm fine with accepting your judgement on that ;) Looks good to me, but I'll leave the final review to you.

@maxkatz6
Copy link
Member

Updated samples and ApiCompat. Thanks!

@maxkatz6 maxkatz6 merged commit 0749f9a into AvaloniaUI:master Jul 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

NumericUpDown control
6 participants