[收藏]DataGridView按回车换列怎样搞!
大家知道,在WinForm开发的系统中,有Header-Detail的结构不少,比如订单、发货单、凭证等等,基本都是Header-Detail结构,而在C#中要开发这样的程序还真有点麻烦,可能是新东西刚出来,要解决这样问题,还真有点烦!同时一般比较好的系统中,你不用Mouse,用键盘就可以操作整个系统。为此,本人专门花了点时间来研究这个问题的解决方案,以和大家共享!
1、首先是换行问题!
DataGridView中,你输入数据,按回车,不会跳到下一列去,而是跳到下一行,如果你想通过KeyPress,KeyDown,KeyUp事件达到目的,好像没什么反应。于是我想肯定有其他的方法可以解决。就到微软的网站上去查,果然有相关情况的介绍,但还是达不到我要的,于是改造一下,就OK了。
基本解决方法如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public class CustomDataGridView : DataGridView
{
protected override bool ProcessDialogKey(Keys keyData)
{
Keys key = (keyData & Keys.KeyCode);
if (key == Keys.Enter)
{
return this.ProcessRightKey(keyData);
}
return base.ProcessDialogKey(keyData);
}
public new bool ProcessRightKey(Keys keyData)
{
Keys key = (keyData & Keys.KeyCode);
if (key == 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;
}
return base.ProcessRightKey(keyData);
}
return base.ProcessRightKey(keyData);
}
protected override bool ProcessDataGridViewKey(KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
return this.ProcessRightKey(e.KeyData);
}
//if (e.KeyCode == Keys.F4)
//{
// return this.ProcessRightKey(e.KeyData);
//}
return base.ProcessDataGridViewKey(e);
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public class CustomDataGridView : DataGridView
{
protected override bool ProcessDialogKey(Keys keyData)
{
Keys key = (keyData & Keys.KeyCode);
if (key == Keys.Enter)
{
return this.ProcessRightKey(keyData);
}
return base.ProcessDialogKey(keyData);
}
public new bool ProcessRightKey(Keys keyData)
{
Keys key = (keyData & Keys.KeyCode);
if (key == 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;
}
return base.ProcessRightKey(keyData);
}
return base.ProcessRightKey(keyData);
}
protected override bool ProcessDataGridViewKey(KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
return this.ProcessRightKey(e.KeyData);
}
//if (e.KeyCode == Keys.F4)
//{
// return this.ProcessRightKey(e.KeyData);
//}
return base.ProcessDataGridViewKey(e);
}
}
}
这样,你输入回车,不会再跳到下一行,而是跳到下一列,只有当你到最后一列时,才会换行。本人试过,基本没有什么Bug,可以拿来做现成的用,大家在写程序时就不需要再写代码了,这个就OK。
那是不是说所有问题都解决了?不是,因为我们在使用的过程中,可能会在DataGridView中使用其他的快捷键,比如微软的标准,按下F4,会弹出下拉列表(如:大家习惯的ComboBox控件就是很好的示例,将光标定位到ComboBox,按下F4,肯定会下拉的,除非自已写来替换掉)。解决这个问题的方法类似!
2、实现快捷功能(键盘实现)。
其实这种方法还蛮简单的,你只需要在protected override bool ProcessDialogKey(Keys keyData)此方法中更改,加一些相关的语句就OK了。如我测试用的:
protected override bool ProcessDialogKey(Keys keyData)
{
Keys key = (keyData & Keys.KeyCode);
if (key == Keys.Enter)
{
return this.ProcessRightKey(keyData);
}
if (key == Keys.F4)
{
if (base.CurrentCell.ColumnIndex == 0)
{
Form1 frm = new Form1();
frm.Show();
}
}
return base.ProcessDialogKey(keyData);
}
{
Keys key = (keyData & Keys.KeyCode);
if (key == Keys.Enter)
{
return this.ProcessRightKey(keyData);
}
if (key == Keys.F4)
{
if (base.CurrentCell.ColumnIndex == 0)
{
Form1 frm = new Form1();
frm.Show();
}
}
return base.ProcessDialogKey(keyData);
}
大家可以看看,是不是很简单?
看起来比较简单,但大家在使用中还是需要注意:首先,你在这已经实现了,你就不要在KeyPress,KeyDown,KeyUp中画蛇添足了。否则,你一定会碰到麻烦问题,然后一直调程序,蛮难找到的。另外,如果你不在这实现,在KeyPress,KeyDown,KeyUp中好像也实现不了,我是试过,基本搞不定,试了几次没结果。就这样吧!哈哈!!!