DoubleUpDown decimal symbol

Jun 4, 2012 at 3:48 PM

Hi,

I've got a DoubleUpDown control and observed different behaviour depending on which decimal symbol I have set in my regional settings.

If I have '.' (point) as my system decimal symbol and write a ',' (comma) in the control, it automatically converts the comma into a dot and save  the right value for the control. (5,66 is saved as 5.66)

Otherwise, if I have ',' (comma) as my decimal symbol and write a '.' (point) in the control, it discards the point (5.66 is saved as 566).

Is this a bug, is anywhere I could control this with a Format String or something like that?

Thanks in advance,

AB.

Coordinator
Jun 4, 2012 at 5:47 PM

The DoubleUpDown control parse the value using the culture set into DoubleUpDown.CultureInfo.  By default, this value is set to the current culture.  When a value is entered in the TextBox, the DoubleUpDown control will try to parse the text value and convert it to a double value.  If it fails, the control will convert the old double value into a string and display it in the TextBox.

 

If you want to control somehow how the DoubleUpDown parse the value, set a specific CultureInfo into the DoubleUpDown.CultureInfo property.

Jun 5, 2012 at 9:37 AM

Thanks!

I tried that but DoubleUpDown.CultureInfo seems to be a ReadOnly property (I don't know if I'm doing something wrong but it gives me an exception whe I try to set a specific CultureInfo). Anyway that was not my concern.

I'm fine with the control taking the current system culture including the decimal separator symbol. For example the '.' (point). In this case, if instead a 'poitn' I write a 'comma', the control itself parse that 'comma' into a 'point', to match the current culture symbol and the value is set correctly and everything is ok. 

I would expect that if a 'comma' is set as current symbol and I write a value with a 'point' (which is very likely to happend using the NumPad) that string would be parsed into a valid value with a 'comma' as decimal symbol (just like Excel does)  and not what it currently does: fails the parse and keeps the old value.

 

Coordinator
Jun 7, 2012 at 5:49 PM

The DoubleUpDown control doesn't work that way.  Internally, it calls the Double.Parse method of the framework.  If the framework doesn't do it, the DoubleUpDown control won't do it either.

 

If for some reason you want to replace the '.' from the NumPad with your current culture decimal separator, the following code may help you out.  Here is the XAML of the DoubleUpDown control.

<xctk:DoubleUpDown x:Name="_ctrl">
   <xctk:DoubleUpDown.InputBindings>
      <KeyBinding Key="{Binding ReplaceDecimalCommand.GestureKey}"
                  Command="{Binding ReplaceDecimalCommand}"
                  CommandParameter="{Binding ElementName=_ctrl}" />
   </xctk:DoubleUpDown.InputBindings>
</xctk:DoubleUpDown>

 

The Command that is being used replace the '.' (NumPad) for the decimal separator of the culture set on the DoubleUpDown control.  Here is the code of the Command.

public sealed class ReplaceDecimalSeparatorCommand : ICommand
{
  public Key GestureKey
  {
    get
    {
      return Key.Decimal;
    }
  }

  public event EventHandler CanExecuteChanged
  {
    add
    {
    }
    remove
    {
    }
  }

  public void Execute( object parameter )
  {
    DoubleUpDown control = parameter as DoubleUpDown;
    if( control == null )
      return;

    TextBox textBox = FindTextBox( control );
    if( textBox == null )
      return;

    CultureInfo culture = control.CultureInfo;
    int selectionStart = textBox.SelectionStart;
    int selectionLength = textBox.SelectionLength;
    string separator = culture.NumberFormat.NumberDecimalSeparator;
    string text = textBox.Text;

    if( selectionLength > 0 )
    {
      text = text.Remove( selectionStart, selectionLength );
    }

    text = text.Insert( selectionStart, separator );

    textBox.Text = text;
    textBox.SelectionStart = selectionStart + separator.Length;
  }

  public bool CanExecute( object parameter )
  {
    return ( parameter is DoubleUpDown );
  }

  private TextBox FindTextBox( DependencyObject d )
  {
    TextBox textBox = d as TextBox;

    if( d != null && textBox == null )
    {
      int count = VisualTreeHelper.GetChildrenCount( d );
      for( int i = 0; i < count; i++ )
      {
        textBox = FindTextBox( VisualTreeHelper.GetChild( d, i ) );
        if( textBox != null )
          break;
      }
    }

    return textBox;
  }
}