How can I use a keypress to run a method? - c#

My form has several buttons such as "Scan" and "Exit". I have seen in many programs where buttons will be useable by keypress. Lots of times the unique key to press is underlined in the text on the button (I don't know how to use an underline option on these forums!). I went to the form and added a keypress event:
private void Form1_KeyPress(object sender, KeyPressEventArgs key)
{
switch (key.ToString())
{
case "s":
Run_Scan();
break;
case "e":
Application.Exit();
break;
default:
MessageBox.Show("I'll only accept 's' or 'e'.");
break;
}
}
But then pressing 's' or 'e' on the form doesn't do anything. Not sure where I'm going wrong here?

Overriding ProcessKeyCommand will accept input from anywhere on the form. You should add a modifier however, since pressing 's' or 'e' in a textbox, for example, will also trigger the action.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
switch (keyData)
{
case Keys.S:
Run_Scan();
break;
case Keys.E:
Application.Exit();
break;
default:
MessageBox.Show("I'll only accept 's' or 'e'.");
break;
}
return base.ProcessCmdKey(ref msg, keyData);
}

I think you are looking for what are called Access Keys: There are defined by the '&' symbol.
Get rid of your KeyPress event handler. You will not need it.
Change the text of your buttons to "&Scan" and "&Exit".
Also: Here are some guidelines about using access keys in windows applications.

key.ToString() is the wrong method to call. You want to access the key property: key.KeyChar.
See the MSDN here for more info on the KeyPressEventArgs, which includes examples.

You can put an ampersand in front of the letter you want to make a hot key for the button in the Text property of your button. You can set the Text property from the Properties pane in the form designer, or you can set it programmatically. Below is an example of programmatic approach.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// make the 'B' key the hot key to trigger the key press event of button1
button1.Text = "&Button";
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("B");
}
}

Related

C# Detect when key gets pressed and trigger a button

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.

Button hold on C# application

I am building a robot car with a Raspberry Pi 3, using C#. I am able to control it with either a button on the user interface or with a keyboard.
The problem with the buttons is that when I click a button, the function won't stop until I press another button. I either need a way of checking while the button is being clicked or one what checks when the button is unclicked.
I have looked through other posts on button holding, but can't really get anything to work.
In the case of key presses, it works correctly because it stops moving when I stop pressing the button. I just add this to the in the XAML page. This is due to the KeyUp bit.
KeyDown="Background_KeyDown_1" KeyUp="Background_KeyUp_1">
This is the C# code.
//Event for when key is pressed
private void Background_KeyDown_1(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
{
KeyDirection(e.Key);
}
//Event when key is unpressed, emulates 'Enter' which represents stop.
private void Background_KeyUp_1(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
{
KeyDirection(Windows.System.VirtualKey.Enter);
}
//This guy is called when a key is pressed or unpressed.
public void KeyDirection(Windows.System.VirtualKey vkey)
{
//Detects which key has been pressed, then calls Direction();
switch (vkey)
{
case Windows.System.VirtualKey.W:
Direction("forwards");
break;
case Windows.System.VirtualKey.A:
Direction("left");
break;
case Windows.System.VirtualKey.S:
Direction("backwards");
break;
case Windows.System.VirtualKey.D:
Direction("right");
break;
case Windows.System.VirtualKey.Enter:
Direction("stop");
break;
default:
Direction("stop");
break;
}
}
As of current, I am unable to find a way of getting this to work. I was hoping someone who has got it to work previously could show me how they did it.
Cheers, Callum :)

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;
}
}
}
}

F10 Key is not caught

I have a Windows.Form and there overriden ProcessCmdKey. However, this works with all of the F-Keys except for F10. I am trying to search for the reason why ProcessCmdKey is not called when I press F10 on my Form.
Can someone please give me a tip as to how I can find the cause?
Best Regards, Thomas
Windows treats F10 differently. An explanation is given in the "Remarks" section here on MSDN
I just tested this code with Windows Forms on .NET 4 and I got the message box as expected.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.F10)
{
MessageBox.Show("F10 Pressed");
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
May be I got your problem, so trying to guess:
Did you set KeyPreview property of your WindowsForm to true ?
This will enable possiblity to WindowsForm proceed keypress events before they pump to the control that holds the focus on UI in that precise moment.
Let me know if it works, please.
Regards.
In my case I was trying to match e.key to system.windows.input.key.F10 and it didn't not work (althougth F1 thru F9 did)
Select Case e.Key
Case is = Key.F10
... do some stuff
end select
however, I changed it to
Select Case e.Key
Case is = 156
... do some stuff
end select
and it worked.
If running into this issue in a WPF app, this blog post shows how to capture the F10 key:
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.SystemKey == Key.F10)
{
YourLogic(e.SystemKey);
}
switch (e.Key)
{
case Key.F1:
case Key.F2:
}
}
Right, and as this is a special key you must add
e.Handled = true;
it tells the caller that you handled it.
So, your code could look like:
switch (e.Key)
...
case Key.System:
if (e.SystemKey == Key.F10)
{
e.Handled = true;
... processing
}

Sending keystrokes to control in .Net

My ActiveX control contains various shapes which are drawn. CTRL-A is used in the control to select all the objects. Similarly CTRL-C to copy, CTRL-V to paste etc.
However, when I insert this control within a Windows form in a .Net application, it does not receive these keyboard events. I tried adding a PreviewKey event, and this does allow certain keystrokes to be sent e.g. TAB, but not these modified keys.
Does anybody know how to redirect modified keystrokes to a user control?
Thanks.
It's possible that the ActiveX control doesn't have focus and is therefore not receiving the key events. You may want to handle the key events at the form level and then call the appropriate methods on your ActiveX control. If you set the KeyPreview property of your form to true your form will receive the key events for all controls on the form. That way, your shortcuts should work no matter what control currently has focus. Here is a quick example you can play with to test this out. Create a new form with several different controls on it and modify the code like so:
public Form1()
{
InitializeComponent();
KeyPreview = true; // indicates that key events for controls on the form
// should be registered with the form
KeyUp += new KeyEventHandler(Form1_KeyUp);
}
void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (e.Modifiers == Keys.Control)
{
switch (e.KeyCode)
{
case Keys.A:
MessageBox.Show("Ctrl + A was pressed!");
// activeXControl.SelectAll();
break;
case Keys.C:
MessageBox.Show("Ctrl + C was pressed!");
// activeXControl.Copy();
break;
case Keys.V:
MessageBox.Show("Ctrl + V was pressed!");
// activeXControl.Paste();
break;
}
}
}
No matter what control has focus when you enter the key combinations, your form's Form1_KeyUp method will be called to handle it.
You need to trap the keys and override the ProcessCmdKey method.
class MyDataGrid : System.Windows.Forms.DataGrid
{
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
...........
}
}
http://support.microsoft.com/kb/320584
KeyPreview is just the wrong method. Try using KeyUp or KeyDown, like this:
private void ControlKeyTestForm_KeyUp(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.A)
this.label1.Text = "Ctrl+A pressed";
}
If you want the containing form to deal with shortcut keys remember to set the KeyPreview property on the form to true then set the KeyDown or KeyUp handlers in the form.
Use Control.ModifierKeys Property to check for Modifier keys.
For example, to check for shift key,
try if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { }
Full example here:
http://msdn.microsoft.com/en-us/library/aa984219%28VS.71%29.aspx

Categories