我有一DataGridView控件dv1,其中有两列A1,A2,A1为只读列,a2为可编辑的DataGridViewTextBoxColumn类型,由于dv1中的各行是在程序运行中才生成的。现在我想在dv1的第二列的第一行开始进行输入,一旦在第一行输入内容按enter后,光标自动跳到下一行的A2列,这样该怎样实现呢? 另外,假设现在光标在a2列的第n行,按enter后跳到N+1行,这样又该怎么办呢? 当然,第二种情况与第一种情况是一样的。
调试欢乐多
dataGridView1.CurrentCell.ColumnIndex 当前单元格列
protected override bool ProcessDialogKey(Keys keyData)
{
if (keyData==Keys.Enter)
{
return this.ProcessRightKey(keyData);
}
return base.ProcessDialogKey(keyData);
}
public new bool ProcessRightKey(Keys keyData)
{
if (keyData == Keys.Enter)
{
//第一种情况:只有一行,且当光标移到最后一列时
if ((base.CurrentCell.ColumnIndex == (base.ColumnCount - 1)) && (base.RowCount == 1))
{
base.CurrentCell = base.Rows[base.RowCount - 1].Cells[0];
return true;
}
//第二种情况:有多行,且当光标移到最后一列时,移到下一行第一个单元
//if ((base.CurrentCell.ColumnIndex == (base.ColumnCount - 1)) && (base.CurrentCell.RowIndex < (base.RowCount - 1)))
//{
// base.CurrentCell = base.Rows[base.CurrentCell.RowIndex + 1].Cells[0];
// return true;
//}
if ((base.CurrentCell.ColumnIndex == (VisibleColumnCount - 1)) && (base.CurrentCell.RowIndex < (base.RowCount - 1)))
{
base.CurrentCell = base.Rows[base.CurrentCell.RowIndex + 1].Cells[0];
return true;
}
isEnterKey = true;
//ProcessDataGridViewKey(new KeyEventArgs(Keys.Enter));
}
return base.ProcessRightKey(keyData);
}
protected override bool ProcessDataGridViewKey(KeyEventArgs e)
{
if (e.KeyCode==Keys.Enter)
{
isEnterKey = true;
return this.ProcessRightKey(e.KeyData);
}
return base.ProcessDataGridViewKey(e);
}
protected override void OnCellEnter(DataGridViewCellEventArgs e)
{
if (isEnterKey && (!CurrentCell.Visible || CurrentCell.ReadOnly))
{
SendKeys.Send("{Enter}");
}
else
{
isEnterKey = false;
base.OnCellEnter(e);
}
}
如果是单选,则输入一个数字选项后,直接跳到下一题的答案选择位。如果是多选,则输入组合数字,如选择了第1项和第3项,则输入“13”然后加回车跳到下一题的答案选择位。
我用的是DataGridView来表示的,具体样式如下:
第1题:1+1=? (单选题) (这里是答案选择单元格:1C1)
选项:1、=1 2、=0 3、=11
第2题:3+2-5=?(单选题) (这里是答案选择单元格:3C1)
选项:1、=0 2、=1 3、=5
第3题:你认为下列哪项是正确的(多选题) (这里是答案选择单元格:5C1)
选项:1、OK 2、OKK 3、OKK
以上是我的一个模拟样式,是个两列的DataGridview,第一列用来保存试题以及选项。第二列用来输入选项。
首先进入输入界面后,光标直接聚集到单元格1C1处,由于是单选。我输入“2”后,直接跳到单元格:3C1处,当在5C1处时,由于是多选题,因此,在我输入选项“13”后(表明我选择是的第1和第3选项),然后必须加一Enter后才能跳到下一题。 以上是我的情景描述,不知道我说得清楚不?因为是数据统计,数据量比较大,录入人员都习惯使用小键盘来直接输入的,因此才有这个要求。
请大家给个建议该怎样解决这个问题呢?
至于跳转,,, 那就更简单了:
//跳转到第三列,第一行
dataGridView1.CurrentCell = dataGridView1[2, 0];
/// 实现按下Enter键是移动到下一单元格,不换行
/// </summary>
/// <param name="msg"></param>
/// <param name="keyData"></param>
/// <returns></returns>
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Enter)
{
SendKeys.Send("{tab}");
}
return base.ProcessCmdKey(ref msg, keyData);
}这个是不换行的 ,你可以试着改成换行的
我是这样解决的:为了简化,我使用了两列的datagridviwe,第一行第一列用来保存题面说明(这一单元格只读),第一行第二列用来准备用户输入答案的。
第二行第一列用来显示上题的所有选项。第二行第二列为只读。
以后以此类推。
当我在奇数行的第二列输入答案后,按Enter后进入跳到下一个输入答案处。
为了实现这种实现,我是无论无论都无法拦截Enter,最后只能重载ProcessCmdKey,在里面执行了两次SendKeys.Send("{Down}");后来实现。 最后回答有位朋友我是怎样知道的单项选择题以及多项选择题的:
我在向datagridview中添加单元格时,根据题型(单选,多选),作为一个Tag值保存在第二列中的,在这里我发现这个tag真是一个好东西。
谢谢各位的参与。我将我的笨办法处理方法分享一下,期望对大家将来有帮助。