'The Enter Key does not close a Form if the Focus is on a Button that is not the AcceptButton
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 ButtonA
was selected but the user can go over ButtonB
orC
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...
Solution 1:[1]
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);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |