How to KeyDown event when you have buttons in your form - c#

I made a program in WinForms that shows a blank screen, and then if you press Enter then something happens..
well i used this code:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
label1.Visible = false;
Colors.Start();
}
Now when I tried to add some buttons to the blank screen, the option to click on Enter just don't work anymore... no matter what I do. and please don't earse this question, I'm kind of new in programming and I know there's alot of questions like that one, but I couldn't understand them...
thanks

Is the form's AcceptButton property assigned to a button?
If so, that could be grabbing the Enter keystroke first.

An example of the suggestion by Hans Passant:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Enter)
{
MessageBox.Show("Enter");
return true; // optionally prevent further action(s) on Enter; such as Button clicks
}
return base.ProcessCmdKey(ref msg, keyData);
}
}
Note that if you return true, then controls like the buttons will not get the Enter keystroke.

Related

C# Visual Studio, how to detect Enter key press when a button has focus

I have the following code that detects the enter key press and works ok. however, if you click a button on the form then it stops working i.e. the button pressed now has focus and enter press goes straight to that button.
private void Form1_Load(object sender, EventArgs e)
{
KeyPreview = true;
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
MessageBox.Show("Enter pressed");
}
}
I have tried the following with no success;
Using forms PreviewKeyEvent instead of keyUp
Using forms KeyDown instead of KeyUp
Creating a button that is selected as the form's 'AcceptButton'
My workaround is to create a button that the form 'selects' on load, which will be clicked on entering. Then to have a timer running to maintain focus on that button in case any others are selected. This seems a bit of a shoddy solution.
Any ideas would be appreciated. Seems like I am missing something obvious.
Phil
Override ProcessCmdKey:
protected override bool ProcessCmdKey( ref Message msg, Keys keyData ) {
if( keyData == Keys.Enter ) {
// Enter is pressed
return true; //return true if you want to suppress the key.
}
return base.ProcessCmdKey( ref msg, keyData );
}

Catch and process KeyPress/KeyDown without modifying text in TextBox

I currently have the following event handler which catches the Ctrl+Enter key combo in my Form code:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter && e.Control)
{
// Stuff
}
}
I also have two non-ReadOnly TextBoxes in the form, one of which is multiline, while the other one isn't. Whenever I hit Ctrl+Enter, the event does get handled, but it also registers as an Enter keypress when the focus is in either TextBox. What I want to do is register the key combo without the Enter keypress modifying the text in either box. Is there any way I could go about doing this?
Your best choice is use ProcessCmdKey: Just add this to your Form add it will work:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.Enter))
{
// Stuff
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
You should use the PreviewKeyDown event instead and set the IsInputKey property accordingly:
private void Form1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Enter && e.Control)
{
// Stuff
e.IsInputKey = false;
}
}
UPDATE: From the name of your handler, I guess you added it to the Form's KeyPress/KeyDown/PreviewKeyDown event. Instead you should register the method I showed above with each TextBox's PreviewKeyDown event.
To not destroy what already works for you, you may leave your code as it is and just add a handler to the TextBox's PreviewKeyDown event where you set IsInputKey to false for the specified keys, but don't do your // Stuff.

Need something like Accept Button in User Control

I need to have a Button on a UserControl (not Form) in a windows application to respond to "Enter" hit, the way a button which is set as the Accept Button of a Form works.
I cannot make the button to be focused, since I need other controls to be focused with tab change.
Any help is really appreciated :)
The AcceptButton is a property of Form and cannot be used for the UserControl. You can simply override ProcessCmdKey though and this will work so long as the user control has focus. Otherwise you will need to use the AcceptButton of the form separately or override the ProcessCmdKey in the form if you have multiple controls which could be active.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Enter)
{
button.PerformClick();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
If you set the Modifier property on the button to "Public", you can use the button as AcceptButton on the form. Unfortunately you cannot do it design-time with the properties window of Visual Studio, but you can do it in code.
public Form1()
{
InitializeComponent();
this.AcceptButton = userControl11.button1;
}
I know it's an old question, and already answered, however I use this in some situations:
private void UserControl11_Load(object sender, EventArgs e)
{
this.FindForm().AcceptButton = Button1;
}

Give focus to textBox on key press

I want to give a textbox focus when the user starts typing anywhere in my app.
My page inherits from LayoutAwarePage.
Can this be achieved ?
Edit:
I got this code:
// In constructor
Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
// Somewhere else in class
void CoreWindow_KeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args)
{
this.setSearchboxFocus((int)args.VirtualKey);
}
private void setSearchboxFocus(int keyCode)
{
if (keyCode == 38)
return;
if (keyCode == 40)
return;
if (this.searchBox.FocusState == Windows.UI.Xaml.FocusState.Unfocused)
{
this.searchBox.Text = "";
this.searchBox.Focus(Windows.UI.Xaml.FocusState.Keyboard);
}
}
For anyone reading this thread in the future, it is because of the webview. I asked a similar question on the msdn forum here. As of Windows 8.1, the webview is implemented as a separate window and completely steals all keyboard input when it has focus without passing any of it up to the controlling application. If you are able to change the HTML in the website being called it may be possible to use javascript listeners to pass events between the application and webview, but I did not test this myself. Unfortunately there does not seem to be any other workaround at this time.
You can handle the KeyDown/KeyUp event for the whole page by subscribing to these events
Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
Window.Current.CoreWindow.KeyUp += CoreWindow_KeyUp
This might help
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
textBox1.Focus();//sets focus to textBox1 when user presses a key on form
}
How about something like this?
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (!textBox1.Focused)
{
textBox1.Focus();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
How about, on the Windows.UI.Xaml.Controls.Page:
protected override void OnKeyDown(KeyRoutedEventArgs e)
{
textBox1.Focus(Windows.UI.Xaml.FocusState.Keyboard);
base.OnKeyDown(e);
}

C# trying to capture the KeyDown event on a form

I am creating a small game, the game is printed onto a panel on a windows form. Now i want to capture the keydown event to see if its the arrow keys that has been pressed, the problem however is that i can't seem to capture it.
Let me explain, on the form i have 4 buttons and various other controls and if the user for instance press one of the buttons (to trigger a game event) then the button has focus and i can't capture the movements with the arrow keys.
I tried something like
private void KeyDown(KeyEventArgs e)
{
if (e.KeyCode == Keys.Left)
{
game.MovePlayer(DonutWarsLibrary.GameObjects.Direction.E);
game.DrawObjects(panel1.CreateGraphics());
}
else if (e.KeyCode == Keys.Right)
{
game.MovePlayer(DonutWarsLibrary.GameObjects.Direction.W);
game.DrawObjects(panel1.CreateGraphics());
}
else if (e.KeyCode == Keys.Up)
{
game.MovePlayer(DonutWarsLibrary.GameObjects.Direction.N);
game.DrawObjects(panel1.CreateGraphics());
}
else if (e.KeyCode == Keys.Down)
{
game.MovePlayer(DonutWarsLibrary.GameObjects.Direction.S);
game.DrawObjects(panel1.CreateGraphics());
}
}
and then when the form key down event was pressed, i used this
private void MainForm_KeyDown(object sender, KeyEventArgs e)
{
KeyDown(e);
}
I also added keydown for the buttons and the various other controls on the windows form, but i am not getting any response back. I have setup a breakpoint inside the function to see if it's being called, but that breakpoint never triggers?
Any ideas?
The most optimal was to have a general KeyDown event that triggers (regardless of what control that currently has focus) and then calls the KeyDown method.
Have you set the KeyPreview property of the form to true? That will cause the form to get a "first look" at key events.
Update: getting this to work properly when a Button has focus seems to be a bit tricky. The Button control intercepts the arrow key presses and moves focus to the next or previous control in the tab order in a manner so that the KeyDown, KeyUp and KeyPress events are not raised. However, the PreviewKeyDown event is raised, so that can be used:
private void Form_KeyDown(object sender, KeyEventArgs e)
{
e.Handled = ProcessKeyDown(e.KeyCode);
}
// event handler for the PreViewKeyDown event for the buttons
private void ArrowButton_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
ProcessKeyDown(e.KeyCode);
}
private bool ProcessKeyDown(Keys keyCode)
{
switch (keyCode)
{
case Keys.Up:
{
// act on up arrow
return true;
}
case Keys.Down:
{
// act on down arrow
return true;
}
case Keys.Left:
{
// act on left arrow
return true;
}
case Keys.Right:
{
// act on right arrow
return true;
}
}
return false;
}
Still, the focus moves around in a rather ugly manner...
I believe the easiest way of solving this problem is through overriding the ProcessCmdKey() method of the form. That way, your key handling logic gets executed no matter what control has focus at the time of keypress. Beside that, you even get to choose whether the focused control gets the key after you processed it (return false) or not (return true).
Your little game example could be rewritten like this:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Left)
{
MoveLeft(); DrawGame(); DoWhatever();
return true; //for the active control to see the keypress, return false
}
else if (keyData == Keys.Right)
{
MoveRight(); DrawGame(); DoWhatever();
return true; //for the active control to see the keypress, return false
}
else if (keyData == Keys.Up)
{
MoveUp(); DrawGame(); DoWhatever();
return true; //for the active control to see the keypress, return false
}
else if (keyData == Keys.Down)
{
MoveDown(); DrawGame(); DoWhatever();
return true; //for the active control to see the keypress, return false
}
else
return base.ProcessCmdKey(ref msg, keyData);
}
Override IsInputKey behaviour
You must override the IsInputKey behavior to inform that you want the Right Arrow key to be treated as an InputKey and not as a special behavior key.
For that you must override the method for each of your controls.
I would advise you to create your won Buttons, let's say MyButton
The class below creates a custom Button that overrides the IsInputKey method so that the right arrow key is not treated as a special key. From there you can easily make it for the other arrow keys or anything else.
public partial class MyButton : Button
{
protected override bool IsInputKey(Keys keyData)
{
if (keyData == Keys.Right)
{
return true;
}
else
{
return base.IsInputKey(keyData);
}
}
}
Afterwards, you can treat your keyDown event event in each different Button or in the form itself:
In the Buttons' KeyDown Method try to set these properties:
private void myButton1_KeyDown(object sender, KeyEventArgs e)
{
e.Handled = true;
//DoSomething();
}
-- OR --
handle the common behaviour in the form: (do not set e.Handled = true; in the buttons)
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
//DoSomething();
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
KeyPreview = true;
KeyDown += new KeyEventHandler(Form1_KeyDown);
}
void Form1_KeyDown(object sender, KeyEventArgs e)
{
System.Diagnostics.Debug.Write(e.KeyCode);
}
}

Categories

Resources