DecimalSeparator: Key.OemPeriod vs Key.Decimal

12 posts, 0 answers
  1. Koen
    Koen avatar
    27 posts
    Member since:
    Apr 2012

    Posted 26 Jun 2013 Link to this post

    Let me start by setting some context:
    • our customers mostly live in Flanders, Belgium; overhere, the default culture nl-BE has  NumberDecimalSeparator = comma, and NumberGroupSeparator = blank space
    • in this post, I will make a clear distinction between "Key.OemPeriod", being the 'regular' period on a keyboard, and "Key.Decimal", being the period on the numpad

    Now, most Belgians have a keyboard layout of Belgium - Period. This means that:
    • While typing text in for instance MS Word, the "Key.Decimal" will be interpreted as a period
    • Mathematical software, like for instance MS Excel, will Always interpret the "Key.Decimal" as a decimal separator. 
          (yes, that's right, even though the NumberDecimalSeparator for the nl-BE culture is a comma).


    Up to the RadNumericUpDown.
    When the culture is set to nl-BE, this control interprets the comma as a decimal separator. So far so good.
    However, when the "Key.Decimal" is pressed, this is not interpreted as a decimal separator, but just like a "Key.OemPeriod" is.
    This is not the expected behavior; it should be interpreted as a decimal separator.

    I'd consider this is a bug.
    Is there any work-around for this issue?

    I tried creating a behavior that would handle the TextBox's PreviewKeyDown event.
    This kind of works, but it has some side effects which makes it not perfect. Any other way to handle this?


    Thanks for your time,
    Koen
  2. Koen
    Koen avatar
    27 posts
    Member since:
    Apr 2012

    Posted 26 Jun 2013 Link to this post

    For anyone running into the same issue, this is the behavior I finally ended up using.


    public
    static class RadNumericUpDownBehavior
     {
     
         /// <summary>
         /// Makes sure that the num-pad period is interpreted as a decimal separator.
         ///
         /// For culture nl-BE, the NumberDecimalSeparator = comma, the NumberGroupSeparator = blank space.
         /// There is a clear distinction between "Key.OemPeriod", being the 'regular' period on a keyboard, and "Key.Decimal", being the period on the num-pad.
         ///
         /// For keyboard layout of Belgium - Period. This means that:
         /// - while typing text in for instance MS Word, the "Key.Decimal" will be interpreted as a period
         /// - mathematical software, like for instance MS Excel, will Always interpret the "Key.Decimal" as a decimal separator.
         ///                         (yes, that's right, even though the NumberDecimalSeparator for the nl-BE culture is a comma).
         ///
         /// When the culture is set to nl-BE, Telerik's RadNumericUpDown interprets the comma as a decimal separator. So far so good.
         /// However, when the "Key.Decimal" is pressed, this is not interpreted as a decimal separator, but just like a "Key.OemPeriod" is.
         /// This behavior fixes that and interpretes the "Key.Decimal" as a decimal separator.
         ///
         /// Was posted on Telerik forum: http://www.telerik.com/community/forums/wpf/numeric-up-down.aspx
         /// </summary>
         public static readonly DependencyProperty ForceNumPadPeriodDecimalSeparatorProperty =
             DependencyProperty.RegisterAttached("ForceNumPadPeriodDecimalSeparator", typeof(bool), typeof(RadNumericUpDownBehavior), new UIPropertyMetadata(false, OnForceNumPadPeriodDecimalSeparatorChanged));
     
         public static bool GetForceNumPadPeriodDecimalSeparator(RadNumericUpDown radNumericUpDown)
         {
             return (bool)radNumericUpDown.GetValue(ForceNumPadPeriodDecimalSeparatorProperty);
         }
     
         public static void SetForceNumPadPeriodDecimalSeparator(RadNumericUpDown radNumericUpDown, bool value)
         {
             radNumericUpDown.SetValue(ForceNumPadPeriodDecimalSeparatorProperty, value);
         }
     
         private static readonly FieldInfo TextBoxField = typeof(RadNumericUpDown).GetField("textBox", BindingFlags.Instance | BindingFlags.NonPublic);
     
         private static void OnForceNumPadPeriodDecimalSeparatorChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
         {
             if (TextBoxField == null)
                 throw new InvalidOperationException("Failed to apply 'ForceNumPadPeriodDecimalSeparator'. Cannot find textBox field on type RadNumericUpDown.");
             var radNumericUpDown = (RadNumericUpDown)dependencyObject;
             if (GetForceNumPadPeriodDecimalSeparator(radNumericUpDown))
                 radNumericUpDown.PreviewKeyDown += RadNumericUpDown_PreviewKeyDown;
             else
                 radNumericUpDown.PreviewKeyDown -= RadNumericUpDown_PreviewKeyDown;
         }
     
         private static void RadNumericUpDown_PreviewKeyDown(object sender, KeyEventArgs e)
         {
             // Key.Decimal = Numpad . and Key.OemPeriod = Keypad .
             if (e.Key != Key.Decimal)
                 return;
     
             e.Handled = true;
             var radNumericUpDown = (RadNumericUpDown)sender;
             var textBox = (TextBox)TextBoxField.GetValue(radNumericUpDown);
             var decimalSeparator = radNumericUpDown.ValueFormat == ValueFormat.Currency
                                        ? GetNumberFormatInfo(radNumericUpDown).CurrencyDecimalSeparator
                                        : GetNumberFormatInfo(radNumericUpDown).NumberDecimalSeparator;
     
             // Simulate the normal RadNumericUpDown behavior when all text is selected:
             // when a decimal separator is typed, clear all text and continue at caret position next to separator.
             if (textBox.SelectionLength == textBox.Text.Length)
             {
                 textBox.Text = decimalSeparator;
                 textBox.Select(textBox.Text.Length, 0);
             }
             else
             {
                 var caretLocation = textBox.SelectionStart;
                 textBox.Text = textBox.Text.Insert(caretLocation, decimalSeparator);
                 textBox.Select(caretLocation + 1, 0);
             }
         }
     
         /// <summary>
         /// This is the same implementation as the internal one on RadNumericUpDown
         /// </summary>
         /// <param name="radNumericUpDown"></param>
         /// <returns></returns>
         internal static NumberFormatInfo GetNumberFormatInfo(RadNumericUpDown radNumericUpDown)
         {
             return radNumericUpDown.NumberFormatInfo ?? CultureInfo.CurrentCulture.NumberFormat;
         }
     }
  3. UI for WPF is Visual Studio 2017 Ready
  4. Koen
    Koen avatar
    27 posts
    Member since:
    Apr 2012

    Posted 28 Jun 2013 Link to this post

    To close this issue, I think there are 2 bugs in the RadNumericUpDown:


    - It interpretes "Key.Decimal" and  "Key.OemPeriod" as being the same, while "Key.Decimal" should always be a decimal separator.
    - It uses NumberStyles.Any to parse text, instead of choosing the right NumberStyle depending on RadNumericUpDown.ValueFormat,
      causing http://www.telerik.com/community/forums/wpf/numeric-up-down/numericupdown-allows-to-enter-commas.aspx

     


    Regards,
    Koen
  5. Konstantina
    Admin
    Konstantina avatar
    2332 posts

    Posted 03 Jul 2013 Link to this post

    Hi Koen,

    Thank you for your feedback.

    We will consider making difference between the pressing of Key.Decimal and Key.OemPeriod keys if we receive more clients' requests. Now, they mean the same for RadNumericUpDown - a dot.

    Regards,
    Konstantina
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  6. Jakkie Esschert van den
    Jakkie Esschert van den avatar
    61 posts
    Member since:
    Sep 2009

    Posted 05 Jul 2013 Link to this post

    Being Dutch I'd like to see the same, or perhaps a mode which treats both a dot and a comma as decimal separator. Nobody here seems to use thousand separators, so both a dot and a comma are generally considered to be a decimal separator. 
  7. Vladi
    Admin
    Vladi avatar
    744 posts

    Posted 10 Jul 2013 Link to this post

    Hello,

    As Konstantina mentioned if we get enough demand for such feature we may consider implementing it as built-in feature in one of our future releases of RadNumericUpDown control.

    You could workaround this issue by handling the inputted symbols for example in the PreviewKeyDown event of the control and implementing a parsing that would consider the entered symbol as decimal separator.

    Regards,
    Vladi
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  8. Technique
    Technique avatar
    11 posts
    Member since:
    Nov 2011

    Posted 04 Dec 2013 Link to this post

    Hi,

    I am french Candian and we also use both the dot and the comma as decimal separators.
    The comma is mostly used though.

    In every software that uses numbers, the Key.Decimal is mapped to the culture of the computer.
    I really don't get why you didn't implement this as it is a normal behavior and it seems to be a source of problem for the most part of the world.

    I am using the GridView and this bugs me quite a lot, if we write "999.99" when the cell ends its edition, the value saved is "0,00" only because of the dot. It is frustrating to have to customize all the Telerik controls we use in order to have a basic functionality.

    If there is a fix or a workaround for this, please let me know.
  9. Vladi
    Admin
    Vladi avatar
    744 posts

    Posted 05 Dec 2013 Link to this post

    Hello,

    As we see that such feature may be desirable to be implemented as a built-in feature in the RadNumericUpDown control you can use our feedback portal where you can add any feature request, bug report and any general feedback about RadControls for WPF and Siverlight.

    You can access the feedback portal from here.

    Regards,
    Vladi
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  10. Tore
    Tore avatar
    9 posts
    Member since:
    Dec 2012

    Posted 17 Sep 2014 Link to this post

    Hello, I got the desired behavior for the Norwegian culture using only XAML, we we also use comma as the NumberDecimalSeparator. Also here, users will be used to using both the comma or the period as the decimal separator. 

    Example:

    Where the XML namespace global is: 
     xmlns:global="clr-namespace:System.Globalization;assembly=mscorlib"

    <telerik:RadNumericUpDown IsEnabled="{Binding IsEditMode, FallbackValue=false}" 
    Value="{Binding TheaterTemperatureSurgeryStart}" Width="50" Minimum="15" Maximum="30" SmallChange="1" 
    Margin="2" ValueFormat="Numeric">
        <telerik:RadNumericUpDown.NumberFormatInfo>
           <global:NumberFormatInfo NumberDecimalDigits="0" NumberDecimalSeparator="," />
        </telerik:RadNumericUpDown.NumberFormatInfo>
    </telerik:RadNumericUpDown> 




  11. Kalin
    Admin
    Kalin avatar
    1208 posts

    Posted 19 Sep 2014 Link to this post

    Hi Tore,

    The best solution I can suggest you for this particular scenario would be to insert the NumberDecimalSeparator of the NumericUpDown control whenever "," or "." are typed in the input field. In order words to insert for example "." in the both cases. You can achieve that by hooking to the PreviewKeyDown of the control and implementing the following event handler:
    private void RadNumericUpDown_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        var num = sender as RadNumericUpDown;
      
        if (e.Key == Key.Decimal || e.Key == Key.OemComma || e.Key == Key.OemPeriod)
        {
            var textBox = e.OriginalSource as System.Windows.Controls.TextBox;
            if (!textBox.Text.Contains(num.NumberDecimalSeparator))
            {
                textBox.Text += num.NumberDecimalSeparator;
                textBox.CaretIndex = textBox.Text.Length;
            }
      
            e.Handled = true;
        }
    }

    Hope this helps.

    Regards,
    Kalin
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  12. Jolanta
    Jolanta avatar
    19 posts
    Member since:
    Oct 2014

    Posted 27 Apr 2015 in reply to Kalin Link to this post

    Hi, 

    is there any possibility to set a decimal and group separator for numeric format, for the whole report, in the standalone telerik designer?

  13. Stef
    Admin
    Stef avatar
    3046 posts

    Posted 29 Apr 2015 Link to this post

    Hi Jolanta,

    I believe your question is related to Telerik Reporting and Report Globalization.

    Please check the linked article and if you need further help, post a question in the corresponding product's forum. Feel free to use the support ticketing system as well, where we can exchange projects and code examples.

    Regards,
    Stef
    Telerik
     

    See What's Next in App Development. Register for TelerikNEXT.

     
Back to Top
UI for WPF is Visual Studio 2017 Ready