Override OnKeyDown DecimalUpDown

Mar 14, 2012 at 12:28 PM

Hello,

 

I have a question about overriding the OnKeyDown event of the DecimalUpDown control.

I want the . (dot) key on de numpad be interpreted as a comma, so that I can enter for example € 2,50 (2 euro and 50 cent), using only the numpad.

I have this working on all my WPF textboxes using the code below:

 

namespace Resources.Controls
{
    public class DecimalKeyTextBox : TextBox
    {
        protected override void OnKeyDown(System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == Key.Decimal)
            {
                e.Handled = true;

                string decimalSeparator = System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator;
                TextCompositionManager.StartComposition(new TextComposition(InputManager.Current, this, decimalSeparator));
            }

            base.OnKeyDown(e);
        }
    }

}

 

But when I want to use the same approach with my DecimalUpDown controls its not working. I am using the following code, the res boolean in the OnKeyDown event returns false:

 

namespace Resources.Controls
{
    public class DecimalKeyDecimalUpDown : DecimalUpDown
    {
        protected override void OnKeyDown(System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == Key.Decimal)
            {
                e.Handled = true;

                string decimalSeparator = System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator;
                bool res = TextCompositionManager.StartComposition(new TextComposition(InputManager.Current, this, decimalSeparator));
            }

            base.OnKeyDown(e);
        }
    }

}

<controls:DecimalKeyDecimalUpDown Grid.Column="3" Grid.Row="1" VerticalAlignment="Center" 
                        Value="{Binding CurrentEntityItem.TouwPrijsPerKg, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, 
                        ValidatesOnExceptions=True, NotifyOnValidationError=True, ConverterCulture=nl-NL}" TabIndex="9" FormatString="C2" SelectAllOnGotFocus="True" Increment="1"/>


I have set the culture of the application to nl-NL at startup, see below:

            CultureInfo culture = new CultureInfo(System.Threading.Thread.CurrentThread.CurrentCulture.Name, true);
            culture.NumberFormat.NumberDecimalSeparator = ",";
            System.Threading.Thread.CurrentThread.CurrentCulture = culture;

Can somebody give me some hints on how I can accomplish the same with my DecimalUpDown controls.

 

Thanks in advance,

 

Marcel

Coordinator
Mar 14, 2012 at 5:03 PM
Edited Mar 14, 2012 at 5:04 PM

Using your sample, I was able to make it work with a little change.

 

The problem is that you aren't creating the TextComposition object with the appropriate IInputElement.  Your DecimalKeyTextBox derives from TextBox while your DecimalKeyDecimalUpDown derives from DecimalUpDown which isn't a TextBox.  The TextBox you see in the DecimalUpDown control comes from its Template.  The "this" parameter you are giving to the TextComposition isn't the TextBox, but the DecimalUpDown control itself.

 

Here is the OnKeyDown method I wrote to make it work:

protected override void OnKeyDown( KeyEventArgs e )
{
  if( e.Key == Key.Decimal )
  {
    TextBox textBox = this.GetTemplateChild( "TextBox" ) as TextBox;

    if( textBox != null )
    {
      string decimalSeparator = Dispatcher.Thread.CurrentCulture.NumberFormat.NumberDecimalSeparator;

      e.Handled = TextCompositionManager.StartComposition( new TextComposition( InputManager.Current, textBox, decimalSeparator ) );
    }
  }

  base.OnKeyDown( e );
}

 

Mar 14, 2012 at 6:46 PM

Thanks Nebuleux, this works great!