How can I prevent that if the user presses one of the arrow keys, a button on the form is focused?
I am programming a small game, so this would prevent the user from being able to move. Sorry for the vague explanation.
EDIT:
The player is a PictureBox with a graphic in it that is moved by:
private async void Form1_KeyDown(object sender, KeyEventArgs e)
In your Form.cs override the ProcessCmdKey like this:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (!msg.HWnd.Equals(Handle) &&
(keyData == Keys.Left || keyData == Keys.Right ||
keyData == Keys.Up || keyData == Keys.Down))
return true;
return base.ProcessCmdKey(ref msg, keyData);
}
A way to handle this scenario is to set form.KeyPreview = true (see MSDN) and then handle the keys in KeyPress / KeyDown event handlers:
Quoting MSDN for KeyPress Event:
To handle keyboard events only at the form level and not enable other controls to receive keyboard events, set the
KeyPressEventArgs.Handled property in your form's KeyPress
event-handling method to true.
Test for arrow in your keysEvent, manage them the way you need and set Handled=true to avoid default behavior (move focus to next control)
What works for me is to set the button property "TabStop" to false and you can also play with the TabIndex property of the controls on the form to technically set what will be focused when the form loads.
TabStop - sets if pressing TAB can set/give focus to the control and when pressing the TAB key it will increment through the controls on the form according to the -
TabIndex - which dictates which control will get focus next.
So if Button A has tabIndex 1 and Button B has tabIndex 2 and button C has tabIndex 3, but Button B has tabStop = false, then pressing TAB will go from button A to Button C, it will skip Button B.
-Keep in mind that not all controls seem to have a "TabStop" property, I have noticed that textbox, button and datagridview does have the property, but stuff like labels and groupbox and picturebox does not have TabStop, only TabIndex.
Related
I have a modal Form with three Buttons, A B and C.
In addition, I have two Buttons: OK and Cancel. The OK Button's DialogResult property is set to DialogResult.OK and the Cancel Button DialogResult.Cancel.
The Form's AcceptButton and CancelButton properties are set to these Buttons.
Currently, the Form is closed when I press the ESC key but if I click the ENTER key when one of the other Buttons (A,B,C) is the Active Control, the Form is not closed. How can I overcome this?
I have two options:
Enter will always close the form (select the focused button and then close it),
The first Enter key press will select the focused button and a second ENTER press will close the Form. The problem is that maybe Button A was selected but the user can go over Button B or C using the arrow keys.
I can't set a DialogResult.OK to the other Buttons, because - in that case - a normal click will also close the Form and I have no way to detect if the event was called because of a Click event or the ENTER key...
If you want to activate the Default button - the Button that is set as the Form's AcceptButton - when another Button has the Focus, but not another Control, as a TextBox, that may want to accept the Enter key, you can override ProcessCmdKey (since pressing the Enter key doesn't raise the KeyDown event and the Click event is raised before the KeyUp event), verify whether the ActiveControl is of type Button (or other type of Controls you want to behave the same way) and set the ActiveControl to your AcceptButton.
The Enter key is transferred to the AcceptButton and the Dialog is Closed, returning DialogResult.OK (since you have already set the Button's DialogResult value):
Note: this assuming that the Container Control is the same.
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Enter) {
if (ActiveControl.GetType() == typeof(Button) &&
ActiveControl != AcceptButton) {
ActiveControl = AcceptButton as Button;
}
}
return base.ProcessCmdKey(ref msg, keyData);
}
In case you just want to change the ActiveControl, setting the Focus to the AcceptButton - so the User needs to press the Enter key twice to confirm, return true after you have changed the ActiveControl, to signal that the input has been handled:
// [...]
if (keyData == Keys.Enter) {
if (...) {
ActiveControl = AcceptButton as Button;
return true;
}
}
return base.ProcessCmdKey(ref msg, keyData);
I have a Windows Form, with a ListView and a TextBox placed right on top of it. Also there is a button named 'Submit' on the Form with AcceptButton set to true.
Now, my requirement is that, whenever I load the form and hit Enter, Submit button gets triggered, which is fine. But, when I select the TextBox and type something in it and then hit Enter, the focus should come to the ListView , but not the AcceptButton
How can I achieve this?
You can set the AcceptButton based on the active control, or as a better option, handle ProcessDialogKey yourself. This is the method which contains the logic for AcceptButton.
So you can override it, for example:
protected override bool ProcessDialogKey(Keys keyData)
{
if (keyData == Keys.Enter)
{
if (this.ActiveControl == this.textBox1)
{
MessageBox.Show("Enter on TextBox1 handled.");
return true; //Prevent further processing
}
}
return base.ProcessDialogKey(keyData);
}
I have a TextBox and set the MiltiLine property to true and AcceptsTab property to false.
When the TextBox has focus and i press Tab it works fine and the next control get the focus, but when i press Ctrl+Tab it works as if AcceptsTab property is set to true and makes a tab character into the TextBox.
The reason i press Ctrl+Tab.. when switching between forms in my MDI application.
Now how to make a Ctrl+Tab when pressed works like Tab when pressed in a MultiLine TextBox?
Well, if you want to suppress Ctrl+Tab press event in textbox, you may hanlde TextBox.KeyDown event with code like this:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.Tab)
{
e.Handled = true;
}
}
This code will suppress Tab behaviour in TextBox. But I don't know if it keeps child forms switching behaviour. Possibly you will have to implement it programmatically. In my simple MDI application with one MDIContainer form and two child forms showed this behaviour doesn't appear by default.
Normally when pressing the TAB key you change the focus to the next control in the given tab order. I would like to prevent that and have the TAB key do something else. In my case I'd like to change focus from a combobox to a completely different control. I can't do this by setting the tab order. I need to do this programatically. Any idea how? It seems like the KeyDown and KeyPress events can't handle TAB key correctly.
Thanks.
Override ProcessDialogKey or ProcessTabKey on your Form and do the logic you want depending on which control is focused.
Based on JRS's suggestion of using the PreviewKeyDown event, this sends the key press through to the control:
private void textBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Tab)
e.IsInputKey = true;
}
Then you can handle the control's KeyDown event if you want to customise the behaviour:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Tab)
{
MessageBox.Show("The tab key was pressed while holding these modifier keys: "
+ e.Modifiers.ToString());
}
}
TextBoxBase alternative
If the control is derived from TextBoxBase (i.e. TextBox or RichTextBox), with the Multiline property set to true, then you can simply set the AcceptsTab property to true.
TextBoxBase.AcceptsTab Property
Gets or sets a value indicating whether pressing the TAB key in a multiline text box control types a TAB character in the control instead of moving the focus to the next control in the tab order.
Override the control's LostFocus event see link below for examples:
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.lostfocus.aspx
Since I am building a UserControl, I ended up using the PreviewKeyDown event on the control. This avoids having to handle key press events on the host form.
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspx
You can try this code on your KeyDown event:
if (e.KeyCode == Keys.Tab) {
//your logic
e.SuppressKeyPress = true;
}
If the button clicked is Tab, then do any custom logic you want, then call SuppressKeyPress to stop the KeyPress event from firing and invoking the normal Tab logic for you.
I have a form with an button which is set as the AcceptButton of the form. The form has several other controls. Now when I press Enter on other controls the form gets closed because of the accept button on the form. Same goes for CancelButton. How do I handle this. I tried hooking on to keypress keydown event of the form and controls. None works. Any work around for this?
Thanks a ton,
Datte
That is how the AcceptButton property works. It specifies the button that is automatically clicked whenever you press <Enter>.
If you don't want this behaviour, don't set it as the AcceptButton. There is no other reason to do it.
Not exactly sure about how you expect your form to function, but you could do something like the following to have a little more control over things:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Enter)
{
// do something
}
if (keyData == Keys.Escape)
{
// do something else
}
return base.ProcessCmdKey(ref msg, keyData);
}
You can remove AcceptButton from form and set the KeyPreview property on the form that'll handle its KeyDown event. There you can check for the Enter key and take the action accordingly.
This is one of the feature of the form i.e.
if button does not have a focus if you still want desired code to be executed when user click Enter...
Set the AcceptButton property of a form to allow users to click a button by pressing the ENTER even if the button does not have focus.
Regards.
Try This One In VB>net
If CType(Me.ActiveControl, Button).Name = Button1.Name Then
End If