disable the default Enter/Return key behavior in a datagridview
Solution 1
You can try something like this in the gridview key down event
Private Sub DataGridView1_Keydown (...) Handles DataGridView1.KeyDown
If e.KeyCode = Keys.Enter Then
' Your code here
e.SuppressKeyPress = True
End If
End Sub
Another option would be to create a custom grid view control
DataGridView.ProcessDataGridViewKey Method
Solution 2
I myself, when disabling the Enter key’s default behavior on a DataGridView
, want to be able to achieve a similar effect to setting DataGridView.StandardTab
to true
. Enabling StandardTab
enables the user to more easily navigate between different controls in a form. This makes it behave more like a ListBox
, especially if the DataGridView
only has one column. The default behavior of of the Enter key and the behavior which I would expect from setting a (nonexistent) DataGridView.StandardEnter
key to true
would be to send the key event to containing controls, probably resulting in the Form.AcceptButton
being activated. The proposed methods of setting KeyEventArgs.SuppressKeyPress = true
in DataGridView.KeyDown
or not even firing DataGridView.KeyDown
when the input key is Enter do not enable “standard” Enter key behavior; these methods instead let the Enter key event get swallowed.
The following shows how I have managed to get “Standard” Enter key behavior (including invoking AcceptButton
appropriately) out of a DataGridView. It is ugly because I do not know a better way to run the logic in Control.ProcessDialogKey()
(which is just to call the Parent (the container)’s ProcessDialogKey()
or return false
if there is no Parent) than to copy it into my own derived class. (I essentially need to use the invalid/impossible base.base.ProcessDialogKey()
syntax to work around System.Windows.Forms
’s non-extensibility in a cleaner manner). Because of this, I am forced to use reflection to access the protected Control.ProcessDialogKey()
method of the parent (the container) Control
object when it exists.
DataGridVew.IsInputKey()
returns true
for Keys.Enter
. This enables it to see the Enter key in its DataGridView.OnKeyDown()
method where it eventually calls DataGridView.ProcessEnterKey()
which reacts to the Enter key in different ways based on the setting of DataGridView.EditMode
. But this also disables sending the key event to ProcessDialogKey()
from where normal controls would bubble the Enter key event to their Parents (enabling AcceptButton
to work, for example). Thus, we revert this behavior by overriding IsInputKey()
and now DataGridView.ProcessDialogKey()
will get called when Enter is pressed.
But that is not enough. DataGridView.ProcessDialogKey()
has a hardcoded call to DataGridView.ProcessEnterKey()
and only calls its base Control.ProcessDialogKey()
if ProcessEnterKey()
returns false. At this point, it would seem common sense to override ProcessEnterKey()
with something that would just return false
when we want standard Enter key behavior. But, alas, it is a non-virtual method. Thus, we are forced to override something we can override, DataGridView.ProcessDialogKey()
, and reimplement it while skipping the call to ProcessEnterKey()
. This is where we are also unable to directly call Control.ProcessDialogKey()
and are forced to use reflection to call the parent/container object’s ProcessDialogKey()
method. But once we successfully make that call, we finally have standard Enter behavior and AcceptButton
is accessible even while the DataGridView
has focus!
/// <summary>
/// A DataGridView with a StandardEnter property which behaves
/// like StandardTab.
/// </summary>
class StandardEnterDataGridView
: DataGridView
{
/// <summary>
/// Like StandardTab but for the Enter key.
/// </summary>
[Category("Behavior"), Description("Disable default edit/advance to next row behavior of of the Enter key.")]
public bool StandardEnter { get; set; }
/// <summary>
/// Implement StandardEnter.
/// </summary>
protected override bool IsInputKey(Keys keyData)
{
if (StandardEnter && keyData == Keys.Enter)
// Force this key to be treated like something to pass
// to ProcessDialogKey() (like the Enter key normally
// would be for controls which aren’t DataGridView).
return false;
return base.IsInputKey(keyData);
}
private static MethodInfo _Control_ProcessDialogKey = typeof(Control).GetMethod("ProcessDialogKey", BindingFlags.Instance|BindingFlags.NonPublic);
protected override bool ProcessDialogKey(Keys keyData)
{
if (StandardEnter && keyData == Keys.Enter)
// Copy the default implementation of
// Control.ProcessDialogKey(). Since we can’t access
// the base class (DataGridView)’s base class’s
// implementation directly, and since we cannot
// legally access Control.ProcessDialogKey() on other
// Control object, we are forced to use reflection.
return Parent == null ? false : (bool)_Control_ProcessDialogKey.Invoke(Parent, new object[] {keyData, });
return base.ProcessDialogKey(keyData);
}
}
Solution 3
You can just use keyPress event:
private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
//You're Code
}
e.Handled = true;
return;
}
Solution 4
Override the DataGridView (write your own that inherits from it), and process the OnKeyDown method.
public partial class UserControl1 : DataGridView
{
public UserControl1()
{
InitializeComponent();
}
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
return;
base.OnKeyDown(e);
}
}
Solution 5
I am adding this foot note to this as I was very interested in this article since it ran close to a different problem I had with the DataGridView. This is that the fact the Enter key takes you to the cell below, preventing a users ability to do simple editing to text in a cell. Having overridden the class and spent much time on this, I finally found the following article: Use Enter to add new line in datagridview cell
If this is your only issue, then to know SHIFT+ENTER works (however unintuitive), might save you a lot of time! Think I will just add a label to the form to remind users.
Comments
-
Ramji almost 2 years
In vb.net datagridview the default Enter/Return key behavior is to move to the next row is there a quick and easy way to avoid that.
Any suggestions are welcome
-
Viku over 10 yearsApplication terminates as soon as it comes to e.suppressKeyPress = true .
-
duardbr about 8 yearsI just change the declaration of my Gride to this new class but nothing happens, ENTER KEY still going to the next row :-/ this.dbGride = new StandardEnterDataGridView();
-
binki about 8 years@duardbr I haven’t looked at this code in a long time, but given that you wrote
this.dbGride = new StandardEnterDataGridView();
in your comment, did you remember to set theStandardEnter
property totrue
? Perhapsthis.dbGride = new StandardEnterDataGridView { StandardEnter = true, };
. Or if you’re using VS Designer try enabling theStandardEnter
property in the Designer’s property grid view. -
duardbr about 8 yearsThanks for reply, yes, StandardEnter is True and nothing happens
-
Birk about 7 yearsThis worked like a charm. Simple but only solution of the proposed, which worked for me.
-
ourmandave over 3 yearsKeyDown, not KeyPress. Scanning the code missed that. My tip off was there's no e.KeyCode in KeyPress.