4

I am developing an on-screen numpad for a WPF touch app. This will appear in a Popup. When a button is pressed, it should send a keystroke to the application, making it look as though the user was typing into a TextBox. This is my code:

// 'key' is set beforehand
InputManager.Current.ProcessInput(new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, Environment.TickCount, key) { RoutedEvent = Control.KeyDownEvent });

This is called within the Button.Click event handler.

So far only Key.Back has worked. None of the digit keys work, and neither does Key.Decimal.

EDIT: I thought using SendKeys would solve the problem, but it just does the same thing.

Why aren't my digit buttons working? I have verified that the correct Key is being passed.

Kendall Frey
  • 43,130
  • 20
  • 110
  • 148
  • 1
    The keys on the numeric pad may have different keys than the top row. This is an untested comment - not an answer. – paparazzo Feb 27 '12 at 17:21
  • @BalamBalam: Neither the top row nor the numpad keys work with the code. Both work on the physical keyboard. – Kendall Frey Feb 27 '12 at 17:27
  • This sounds like a roundabout way of achieving something. Could you not implement all your keypress functions in a third party helper class and get both the Popup keypad, or the keyboard to input to that? – Dr. Andrew Burnett-Thompson Feb 27 '12 at 17:31
  • @Dr.AndrewBurnett-Thompson: I have no special key handling. Just a `TextBox`. – Kendall Frey Feb 27 '12 at 17:34
  • Ok so why not have on the popup key clicked "TextBox.Text += newKeyCharacter" ? If the popup control doesn't have a reference of the underlying control to set the text, then use an eventing pattern like .NET events or EventAggregator to get the data from the popup control to the textbox – Dr. Andrew Burnett-Thompson Feb 27 '12 at 17:36
  • @Dr.AndrewBurnett-Thompson The caret position will then be meaningless, causing confusion to users. And I do have a `KeyDown` event handler, which stores the value of the textbox for validation purposes. If the handler is not called, it may lead to more confused users. – Kendall Frey Feb 27 '12 at 17:43
  • Ok, so use TextBox.Text.Insert to insert at the caret position: http://stackoverflow.com/questions/2117259/insert-text-into-wpf-textbox-at-caret-position. Your KeyDown handler simply needs to call a separate function to perform validation, and make sure the popup calls the same function – Dr. Andrew Burnett-Thompson Feb 27 '12 at 20:54
  • Are you doing only `KeyDown`? You might need to do the `KeyPress` and `KeyUp` as well. – default.kramer Feb 27 '12 at 21:20
  • There is no `KeyPress` event (I wish there was) and I just need to simulate a keypress so that a `TextBox` will pick it up. – Kendall Frey Feb 27 '12 at 21:25
  • does SendKeys work for you? http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.send.aspx – kenny Feb 27 '12 at 21:44
  • That is Windows Forms. It would probably work, but it would be nicer to have a solution in WPF. – Kendall Frey Feb 27 '12 at 21:47

2 Answers2

1

Following our discussions in comments, I suggest you consider an approach like this. I don't know the full requirement, but splitting the functionality up and making the application less monolithic is always a good approach!

First up, a pseudo-UML diagram would be this:

Class depedendency diagram

Your three functions would be implemented as follows (pseudocode):

UserControl1.InsertCharacter(string character)
{
    textBox1.Text = textBox1.Text.Insert(textBox1.CaretIndex, character); 
    this.ValidateInput();
}

UserControl1.ValidateInput()
{
    // Perform validation
}

UserControl1.OnKeyDown()
{
    // Perform validation
    this.ValidateInput();
}

UserControl2.AppendCharacter(string clickedCharacter)
{
    this.userControl1.InsertCharacter(clickedCharacter); 
}

To further decouple UserControl2 from UserControl1 as I mentioned you could use eventing patterns such as .NET events or EventAggregator.

Dr. Andrew Burnett-Thompson
  • 20,980
  • 8
  • 88
  • 178
  • Thanks for the good answer. I'm still looking for an approach that simply presses a key, but if I can't find one, I will accept this. – Kendall Frey Feb 27 '12 at 21:04
  • 2
    Im sure there is one, I would look into the UIAutomation Framework as this can simulate mouse/key input (its mainly used for automation testing). However the point I'm trying to make is, if possible, its good to avoid this and move logic out of the view interactions and into specific functions in code-behind, or better yet, into ViewModels in an MVVM application – Dr. Andrew Burnett-Thompson Feb 27 '12 at 21:09
0

Take a look at http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/b657618e-7fc6-4e6b-9b62-1ffca25d186b/. WPF text box has issues handling certain keys.

From the article:

var eventArgs = new TextCompositionEventArgs(Keyboard.PrimaryDevice, 
new TextComposition(InputManager.Current, Keyboard.FocusedElement, key));  
eventArgs.RoutedEvent = TextInputEvent;  

InputManager.Current.ProcessInput(eventArgs); 
Raj Ranjhan
  • 3,869
  • 2
  • 19
  • 29