I have a strange problem. In Winforms app i have a datagridview where i implemented some code for moving inside of it with arrow keys and enter key...
class CalibDataGridView : System.Windows.Forms.DataGridView
{
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
int row = 0;
int col = 0;
// return base.ProcessCmdKey(ref msg, keyData);
switch (keyData)
{
case Keys.Down:
return true;
case Keys.Up:
return true;
case Keys.Right:
row = this.CurrentCell.RowIndex;
col = this.CurrentCell.ColumnIndex;
while (true)
{
col++;
if (col == this.Columns.Count)
{
row++;
col = 0;
}
if (row == this.Rows.Count)
{
col = 0;
row = 0;
}
if (!this[col, row].ReadOnly && this[col, row].Visible) break;
}
this.CurrentCell = this[col, row];
return true;
case Keys.Left:
row = this.CurrentCell.RowIndex;
col = this.CurrentCell.ColumnIndex;
while (true)
{
col--;
if (col < 0)
{
row--;
col = this.Columns.Count - 1;
}
if (row < 0)
{
row = this.Rows.Count - 1;
col = this.Columns.Count - 1;
}
if (!this[col, row].ReadOnly && this[col, row].Visible) break;
}
this.CurrentCell = this[col, row];
return true;
case Keys.Enter:
row = this.CurrentCell.RowIndex;
col = this.CurrentCell.ColumnIndex;
while (true)
{
row++;
if (row == this.Rows.Count)
{
row = 0;
}
if (!this[col, row].ReadOnly && this[col, row].Visible) break;
}
this.CurrentCell = this[col, row];
return true;
default:
return base.ProcessCmdKey(ref msg, keyData);
}
}
}
The code works fine, but i'm having a problem implement function to move to next control when TAB key is pressed. I added some code in PreviewKeyDown function of datagridview:
private void dgvRepeatability1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.PageDown && tbcMain.SelectedIndex > 0)
{
tbcMain.SelectedIndex--; //changes tab page
}
else if (e.KeyCode == Keys.PageUp && tbcMain.SelectedIndex < 7)
{
tbcMain.SelectedIndex++;
}
else if (e.KeyCode == Keys.Tab) //does not work like it should!!!!
{
Console.Beep(1000, 200);
this.SelectNextControl((Control)sender, true, true, true, true);
}
}
This last code works in strange way... when triggered it somewhere in the background changes focus like it should (it beeps and the next control changes background color so i can see it is focused), but then i lose focus on the whole form... i can press TAB or ARROW KEYS or any other key and nothing happens....
If i minimize the form and then maximize it again the focus goes to the next control like it should in the first place and everything works like it should.
I also tryed change focus with .Select() and .Focus() and did not work.
Thanks in advance for help!
You can use SelectNextControl:
private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
{
if ( e.KeyCode == Keys.Tab )
{
e.Handled = true;
this.SelectNextControl((Control)sender, true, true, true, true);
}
You can also find the next control yourself:
private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
{
if ( e.KeyCode == Keys.Tab )
{
e.Handled = true;
var dataGrid = (DataGridView) sender;
var tabIndex = dataGrid.TabIndex;
var controls = this.Controls.Cast<Control>().Where( r => r.TabIndex > tabIndex );
if ( controls.Any() )
{
controls.OrderBy(r => r.TabIndex).First().Select();
}
else
{
this.Controls.Cast<Control>()
.Where( r => r.TabIndex <= tabIndex )
.OrderBy( r => tabIndex )
.First()
.Select();
}
}
}