I have a KeyDown event in which in DataGridView, when pressed enter key, selection moves to next column and not the next row. The code I have written only works when the cells are not in edit mode. When the cells are cell end edit, selection moves to next row same column. Can someone explains me?
private void dataGridView_voucherdetail_KeyDown(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = true;
if (e.KeyData == Keys.Enter)
{
int iCol = dataGridView_voucherdetail.CurrentCell.ColumnIndex;
int iRow = dataGridView_voucherdetail.CurrentCell.RowIndex;
if (iCol < dataGridView_voucherdetail.Columns.Count - 1)
{
iCol = iCol + 1;
}
else if (iCol == dataGridView_voucherdetail.Columns.Count - 1 && iRow < dataGridView_voucherdetail.Rows.Count - 1)
{
iCol = 0;
iRow = iRow + 1;
}
dataGridView_voucherdetail.CurrentCell = dataGridView_voucherdetail[iCol, iRow];
}
}
The issue you describe is coming from the fact the when a grids cell is in “Edit Mode”, it will be the “cell control” that has its KeyDown
event triggered when the user presses keys. This is why the “Grids” KeyDown
event is not firing when a cell is in edit mode.
In most cases, the strategy to get a cells key press event is to use the grids EditingControlShowing
event. This event will fire when a cell goes into “Edit Mode.” In the event, we would cast the grid cell to a regular TextBox
, then wire up that text boxes KeyPress
event. Then as the user types text into the cell, the text boxes KeyPress
event will fire and we can examine the pressed keys. Sounds promising, however there is one issue in relation to what you are doing…
The text boxes
KeyPress
event will NOT fire when the user presses the “Enter” key.
The grid will “swallow” the Enter key immediately and exit its edit mode. If we are simply preventing the user from entering invalid characters for something like a number only cell, this is fine. However, in this case where want to “capture” the “Enter” key, we need to do something else.
Given this, I suggest that instead of wiring up the text boxes KeyPress
event… we wire up the text boxes PreviewKeyDown
event. This event fires when the user presses a key AND it will capture it BEFORE the grid swallows it if it is the “Enter” key. Problem here is that we can not set the grids current row inside that event without problems.
However, we CAN look for the “Enter” key to know if the user is “leaving” the edited cell. In other words, if the user presses the "Enter" key while in “Edit Mode” we want to know this later when the grid eventually “leaves” that edited cell.
This is where the grids CellEndEdit
event may come in handy. This event will fire when the user tries to “leave” an edited cell. This means leaving the cell by pressing the Tab key, arrow keys or even clicking on another cell. In all those cases, we do NOT want to change the cells next location. BUT… if the cell is ending its edit because the user pressed the “enter” key… we DO want to change the next current cell.
Therefore, if we knew that the reason the cell was ending its edit is because the user pressed the “Enter” key, then… we would know to change the grids next current cell. So, one way to do this may go something like…
Create a global boolean variable and set it to false …
bool EndEditBecauseEnterPressed = false;
Then wire up the grids EditingControlShowing
event to grab the edited cell and wire up its PreviewKeyDown
event. This may look like…
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) {
TextBox editedTB = e.Control as TextBox;
if (editedTB != null) {
editedTB.PreviewKeyDown -= new PreviewKeyDownEventHandler(textBox_PreviewKeyDown);
editedTB.PreviewKeyDown += new PreviewKeyDownEventHandler(textBox_PreviewKeyDown);
}
}
Next, we implement the textbox_PreviewKeyDown
event. It does ONLY one thing… it looks for the “Enter” key. If the “Enter” key is pressed, them we simply set our global variable EndEditBecauseEnterPressed
to true
.
We KNOW that since the user pressed the “Enter” key that the grids CellEndEdit
will fire next and it is there where we can check the EndEditBecauseEnterPressed
variable. If it is true, then we want our code to move the current cell to the right.
These two events may look something like…
private void textBox_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) {
if (e.KeyCode == Keys.Enter) {
EndEditBecauseEnterPressed = true;
}
}
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) {
if (EndEditBecauseEnterPressed) {
if (dataGridView1.CurrentCell.ColumnIndex == dataGridView1.Columns.Count - 1) {
if (dataGridView1.CurrentCell.RowIndex < dataGridView1.Rows.Count - 1) {
dataGridView1.CurrentCell = dataGridView1[0, dataGridView1.CurrentCell.RowIndex + 1];
}
}
else {
if (dataGridView1.CurrentCell.RowIndex < dataGridView1.Rows.Count - 1) {
SendKeys.Send("{up}");
}
dataGridView1.CurrentCell = dataGridView1[dataGridView1.CurrentCell.ColumnIndex + 1, dataGridView1.CurrentCell.RowIndex];
}
EndEditBecauseEnterPressed = false;
}
}
I hope this makes sense and helps.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.