C# Detect when key gets pressed and trigger a button - c#

So I'm trying to make a simple calculator. The user can only input the numbers by the buttons on the form or by the numpad. This is the code I have:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
string key = "";
switch (e.KeyCode)
{
case (Keys.NumPad1):
key = "1";
break;
case (Keys.NumPad2):
key = "2";
break;
default:
break;
}
txt_string.Text = txt_string.Text + key;
}
If I make a breakpoint on the KeyDown function and press the Numpad keys (and every other keys) the program doesnt even comes to that breakpoint.
Do I have to change something on my Form to detect the Keys?

You'll need to set KeyPreview to true (property on the form). Also, I would advise against trying to debug the behaviour - because you may affect the behaviour you're testing (Debug.WriteLine()) is your friend here.

Just to point out that many keyboard doesnt have numpad. You can check if the key is a integer.
void Form1_KeyDown(object sender, KeyPressEventArgs e)
{
if (char.IsDigit(e.KeyChar))
{
txt_string.Text += e.KeyChar;
}
}
This is more a Code Review than a solution though.

Related

How to make TextBox to receive only number key values using KeyDown Event in C#?

This code in my form updates the textBox1.Text twice whenever number keys are pressed.
private void textBox1_KeyDown( object sender, KeyEventArgs e ) {
//MessageBox.Show();
if( char.IsNumber((char)e.KeyCode) ) {
textBox1.Text += (char)e.KeyCode;
}
}
Explain why if you can?
Modify the code or provide me a better solution for this.
Input ( in textbox1 ):
54321
Output:
1234554321
When you press a key, a character is already appended to your TextBox. Then you run the following code and, if the key represents a number, you append it again:
if (char.IsNumber((char)e.KeyCode)) {
textBox1.Text += (char)e.KeyCode;
}
If you want to suppress any key that's not a number, you could use this instead:
e.SuppressKeyPress = !char.IsNumber((char)e.KeyCode);
From the syntax I assume you are using WinForms for the following answer.
The key pressed event is not suppressed, so it still works like a normal key pressed event and adds the character to the text of the box. Additionally you add the character to the text yourself once again.
Try to suppress the key pressed event in case a key is pressed, you do not want to allow.
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (!char.IsNumber((char)e.KeyCode))
{
e.SuppressKeyPress = true;
}
}
You can try like this:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = !(e.KeyValue >= 48 && e.KeyValue <= 57);
}
Check New keyboard APIs: KeyEventArgs.SuppressKeyPress
The problem is that "Handled" doesn't take care of pending WM_CHAR
messages already built up in the message queue - so setting Handled =
true does not prevent a KeyPress from occurring.
In order not to break anyone who has currently got e.Handled =
true, we needed to add a new property called SuppressKeyChar. If we
went the other way, if "handling" a keydown suddenly started to
actually work, we might break folks who accidentally had this set to
true.
Try this code to accept numbers only
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar))
e.Handled = true;
}

Handling arrow key events on a winform textbox without overriding

I have a situation where I'm provided with a WinForms TextBox instance which I want to attach autocomplete functionality to.
I've got the autocomplete (string matching + dropdown) all figured out and it works reliable so far.
What is the ability to navigate the dropdown with the keyboard (as is the norm with this sort of UI).
The natural solution would be to handle KeyDown (or somesuch) event for the textbox and moving the selection in the dropdown accordingly.
However, it happens that to do this, you need to override the IsInputKey() event to allow capture of arrow key events. The alternative is to override ProcessCmdKey() and handle the event there. The problem with these two is that I cannot override anything since I can't replace the textbox instance.
Edit: Let's assume I have the code below:
void _textBox_KeyDown(object sender, KeyEventArgs e)
{
if (_dropdown.Visible)
{
// TODO The stuff below fails because we need to either handle ProcessCmdKey or override IsInputKey
switch (e.KeyCode)
{
case Keys.Tab:
{
// click selected item
_dropdown.Items[GetSelectedItemIndex()].PerformClick();
break;
}
case Keys.Down:
{
// select next (or first) item
int i = GetSelectedItemIndex() + 1;
if (i >= _dropdown.Items.Count) i = 0;
_dropdown.Items[i].Select();
break;
}
case Keys.Up:
{
// select previous (or last) item
int i = GetSelectedItemIndex() - 1;
if (i < 0) i = _dropdown.Items.Count - 1;
_dropdown.Items[i].Select();
break;
}
}
}
}
Them problem with the code above is that it is never called. The event is never triggered for arrow keys. More info: Up, Down, Left and Right arrow keys do not trigger KeyDown event
I hope i haven't missunderstood you, but is this a solution:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Down)
{
// Place logic for textbox here
}
}
I'd use a KeyDown event on the form and then compare the keycode with the Keys.Down keycode
Not working
see here: Up, Down, Left and Right arrow keys do not trigger KeyDown event
I may not be understanding your question entirely, but wouldn't an approach like this work?
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
comboBox1.Text = //results of your matching algorithm.
}
private void textBox1_Validated(object sender, EventArgs e)
{
textBox1.Text = (string) comboBox1.Text;
}

KeyPress and KeyDown events

Hello I'm trying to make a program in WF that uses the KeyPress event.
I've written the following code:
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
while (true)
{
switch (e.KeyChar)
{
case (char)68:
MessageBox.Show("Test");
break;
}
}
}
But when I execute the program and press the key the message box doensn;t appear.
Does anyone have any suggestions or knows how to fix this?
I've also been told that a KeyDown event could work but I don't know how to work with those either.
Don't use while(true) in an event handler. It will loop infinitely.
Just do
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
switch (e.KeyChar)
{
case (char)68:
MessageBox.Show("Test");
break;
}
}
Also is seems cleaner to compare the pressed key to the actual character rather than the ASCII code:
switch (e.KeyChar)
{
case 'D':
MessageBox.Show("Test");
break;
}
You need to set Form.KeyPreview
e.g.
In your form
this.KeyPreview =true;

Are some keyboards more loquacious than others?

The lead developer says that when he uses my app, his keyboard beeps when he moves between TextBoxes on the TableLayoutPanel via the directional arrow keys.
However, I hear no such aural activity.
Here's my code:
// Had to intercept Up and Down arrows from Windows
private void textBoxPlatypi_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) {
TextBox tb = (TextBox)sender;
if (e.KeyCode.Equals(Keys.Up)) {
SetFocusOneRowUp(tb.Name);
return;
}
if (e.KeyCode.Equals(Keys.Down)) {
SetFocusOneRowDown(tb.Name);
return;
}
}
private void textBoxPlatypi_KeyDown(object sender, KeyEventArgs e) {
TextBox tb = (TextBox)sender;
if (e.KeyCode.Equals(Keys.Left)) {
SetFocusOneColumnBack(tb.Name);
e.Handled = true;
return;
}
if (e.KeyCode.Equals(Keys.Right)) {
SetFocusOneColumnForward(tb.Name);
e.Handled = true;
return;
}
}
..He thought maybe I needed "e.Handled" but that is not available in the PreviewKeyDown event.
Is there a way to suppress the beeping (which apparently occurs only with certain keyboards or specific setups (he's using Windows7, I'm on XP still))?
UPDATE
I've got this code now:
private void textBoxPlatypus1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) {
switch (e.KeyCode) {
case Keys.Down:
case Keys.Up:
e.IsInputKey = true;
break;
}
}
private void textBoxPlatypus1_KeyDown(object sender, KeyEventArgs e) {
TextBox tb = (TextBox)sender;
if (e.KeyCode.Equals(Keys.Up)) {
SetFocusOneRowUp(tb.Name);
e.Handled = true;
return;
}
if (e.KeyCode.Equals(Keys.Down)) {
SetFocusOneRowDown(tb.Name);
e.Handled = true;
return;
}
if (e.KeyCode.Equals(Keys.Left)) {
SetFocusOneColumnBack(tb.Name);
e.Handled = true;
return;
}
if (e.KeyCode.Equals(Keys.Right)) {
SetFocusOneColumnForward(tb.Name);
e.Handled = true;
return;
}
}
...but he still hears the beeping (I don't).
He's in Alaska and using Windows 7; I'm in California and using XP. I don't know if some combination/mismatch there is the problem...
UPDATED AGAIN
I know this may be shocking to some, but the Alaska/California disconnection has nothing to do with it. I'm now hearing the beeps, too, and it's not from the arrow keys. It's when a value is entered in a TextBox and then, if that text box already has a character, focus is moved to the next textBox and the value is entered there (this is my code that causes this to happen). But the irritating beeping seems to be random - I haven't figured out the pattern for when it beeps (sometimes it does, sometimes it doesn't)...has anybody ever run across anything like that, or, better yet, know how to suppress the beep? All I'm doing is pressing either the "1" or the "2" key above the keyboard.
There is no way in the PreviewKeyDownEvent to Handle / Supress a KeyEvent like there is in the normal KeyDown Event. What the documentation suggests is to set the PreviewKeyDownEventArgs.IsInputKey property to true in order to handle key presses that are not available normally in the KeyDown Event.
From above Link, they are using a button as an example:
Some key presses, such as the TAB, RETURN, ESC, and arrow keys, are typically ignored by some controls because they are not considered input key presses... By handling the PreviewKeyDown event for a Button and setting the IsInputKey property to true, you can raise the KeyDown event when the arrow keys are pressed. However, if you handle the arrow keys, the focus will no longer move to the previous or next control.
Try this:
e.SuppressKeyPress = true;

How to record typing in C# (keyListener)

I want to write a simple text to speech program.
First, I want to make the program play only the written symbol. For example, if I type 'a' I want the program to say 'a' (I have recorded all of them), so when I type a word, it should spell it.
However, I am a beginner in C# and .Net and don't how to make the program understand the text I type. For example, in java I heard that there is a keyListener class, but I don't know which class should I use. I looked on MSDN but couldn't find it.
Which class or function should I use to listen to typed keys?
I suppose you are planning to use Windows Forms to achieve this.
The solution would be pretty simple. These events include MouseDown, MouseUp, MouseMove, MouseEnter, MouseLeave, MouseHover, KeyPress, KeyDown, and KeyUp. Each control has these events exposed. You just need to subscribe to it.
Please refer to this
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keydown.aspx
There would be a little bit of logic to find whether a complete word has been typed or not. A simple soultion would be , when space has been pressed, you can assume a word has been completed. Its very crude logic, as the user may have typed in wrong spelling and want hit backspace and correct the spelling. You may want to add lag to it.
If you are using Visual Studio like every other C# developer here is a more detailed code example:
Create a Windows Form and go to the [Design].
Select its properties (RMB=>properties), navigate to Events and double click LMB on KeyDown
VS will create and bind the event for you
Handle the KeyEventArgs depending on its value.
Example:
private void NewDialog_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyData)
{
case Keys.A:
{
MethodToOutputSound(AEnum);
break;
}
case Keys.B:
{
MethodToOutputSound(BEnum);
break;
}
case Keys.F11:
{
DifferentMethod();
break;
}
case Keys.Escape:
{
this.Close();
break;
}
default:
{
break;
}
}
}
Or use a lot of ifs
private void NewDialog_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyData == Keys.A)
{
MethodToOutputSound(AEnum);
}
if(e.KeyData == Keys.B)
{
MethodToOutputSound(BEnum);
}
...
}
Create a Windows Form with a TextBox in it. Handle the KeyPress event - that will give you the actual character that the user types. KeyDown and KeyUp won't help you.
You need to check the KeyChar property. Like this:
void MyEventHandler(object sender, KeyPressEventArgs e) {
// Do stuff depending on the value of e.KeyChar
}
private void button1_Click_1(object sender, EventArgs e)
{
string word = textBox1.Text;
foreach (char i in word)
{
switch (i)
{
case 'a':
case 'A': { // play sound a
break;
}
default:
{
// play no sound
break;
}
}
}
}

Categories