I want to make the DataGridView more handy while manipulating the KeyDown event, like the KeyEnter for moving one cell to the right, or using left, down or up. I have some special use cases where I want to check first the cell and depending on that I can discard this event for example or point it to an another cell. This is working fine until I set the "multiselect" feature to true. Then the complete process of leaving focus and set the right focus, per cell is not working fine anymore. Please find some sample code below:
private bool GridNavigation(Keys keys)
{
if (dataGridView1.CurrentRow == null)
{
return true;
}
int iColumn = dataGridView1.CurrentCell.ColumnIndex;
int iRow = dataGridView1.CurrentCell.RowIndex;
if (keys == Keys.Enter || keys == Keys.Right)
{
for (int i = iColumn + 1; i <= dataGridView1.Columns.Count - 4; i++)
{
if (!dataGridView1.Rows[iRow].Cells[i].ReadOnly)
{
dataGridView1.Rows[iRow].Cells[i].Selected = true;
break;
}
if (i == dataGridView1.Columns.Count - 4 && dataGridView1.Rows.Count - 1 != iRow)
{
if (((IDictionary<int, int>)dataGridView1.CurrentRow.Tag).SingleOrDefault(p => p.Key == (int)clsDefinitions.ZeilenIndikator.Typ).Value == (int)clsDefinitions.ZeilenTyp.PassLängeAusgangswert)
dataGridView1.CurrentCell = dataGridView1[0, iRow + 2];
else
dataGridView1.CurrentCell = dataGridView1[0, iRow + 1];
return true;
}
}
return true;
}
else if (keys == Keys.Left)
{
for (int i = iColumn - 1; i >= 0; i--)
{
if (!dataGridView1.Rows[iRow].Cells[i].ReadOnly)
{
dataGridView1.Rows[iRow].Cells[i].Selected = true;
break;
}
}
return true;
}
else
return false;
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Enter || keyData == Keys.Right || keyData == Keys.Left)
{
return GridNavigation(keyData);
}
return base.ProcessCmdKey(ref msg, keyData);
}
So what can be done here. You can easily reproduce by open a new Project and just put a DataGridView in the form and add for example 10 columns or more.
If there's something else I can provide, please let me know.
In your
GridNavigationmethod, under both conditions,if (keys == Keys.Enter || keys == Keys.Right)andelse if (keys == Keys.Left), the guilty party here is the recurring line:What went wrong?
When
dataGridView1.MultiSelect == falsethe above line effectively sets the current cell, not just theSelectedproperty. I.E:CurrentCell = Rows[0].Cells[0],Rows[0].Cells[0].Selected = true->or EnterRows[0].Cells[1].Selected = trueCurrentCell = Rows[0].Cells[1]Rows[0].Cells[0].Selected = falseHowever, when
dataGridView1.MultiSelect == truethe same line of code does not set the current cell. So the current cell remains selected as well as the adjoining cell to the left or right respectively. I.E:CurrentCell = Rows[0].Cells[0],Rows[0].Cells[0].Selected = true->or EnterRows[0].Cells[1].Selected = trueCurrentCell = Rows[0].Cells[0]Rows[0].Cells[0].Selected = true->or EnterRows[0].Cells[2].Selected = true.Rows[0].Cells[1].Selected = true...again.Solution
If you want it to behave the same as
MultiSelect = falseand only have one selected cell when you navigate left or right, just replace the guilty lines of code with:If you want to retain the previously selected cells, replace the guilty lines of code with: