上次因工作需要,需要在DataGridView中添加Combobox及DateTimePicker,于是查询了各种资料,整理后最终实现了想要的效果,现在把相关操作及遇到的问题分享一下。
1.建立DataGridView,绑定数据源
2.将Combobox及DateTimePicker添加到DataGridView控件集合中
3.相关事件,单元格切换触发,显示下拉框及时间控件,CurrentCellChanged
4.时间控件值、下拉框值赋值给单元格,SelectedIndexChanged,TextChange
5.考虑滚动条滚动、列宽改变时,单元格位置发生变化
遇到问题:
1.显示下拉框、时间控件的事件,最开始用点击事件,后面感觉CurrentCellChanged比较好,这个看实际需要
2.焦点问题,时间控件值、下拉框值赋值给当前单元格会有问题,需要通过局部变量来准确赋值,查询修改对应的单元格
3.考虑滚动条滚动时,单元格位置发生变化
效果图及代码如下,第一次写博客,如果有什么问题请原谅
代码:
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
//绑定数据表
BindData();
tg.Controls.Add(dateTimePicker1);//时间
dateTimePicker1.Visible = false; //先不让它显示
tg.Controls.Add(cb);//下拉框
cb.Visible = false;//先不让它显示
cb.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;//只能下拉
cb.SelectedIndexChanged += new EventHandler(cb_SelectedIndexChanged);
dateTimePicker1.TextChanged += new EventHandler(dtp_TextChange);
tg.ColumnWidthChanged += OrderGrid_ColumnWidthChanged;
tg.CurrentCellChanged += OrderGrid__CurrentCellChanged;//
tg.Scroll += OrderGrid_Scroll;
}
DateTimePicker dateTimePicker1 = new DateTimePicker();
ComboBox cb = new ComboBox();
DataTable dtData = new DataTable();
int ColumnIndex = 0;
int RowIndex = 0;
/// <summary>
/// 为避免连接数据库,这里手工构造数据表,实际应用中应从数据库中获取
/// </summary>
private void BindData()
{
dtData.Columns.Add("ID");
dtData.Columns.Add("Name");
dtData.Columns.Add("Sex");
DataRow drData;
drData = dtData.NewRow();
drData[0] = 1;
drData[1] = "张三";
drData[2] = "1";
dtData.Rows.Add(drData);
drData = dtData.NewRow();
drData[0] = 2;
drData[1] = "李四";
drData[2] = "1";
dtData.Rows.Add(drData);
drData = dtData.NewRow();
drData[0] = 3;
drData[1] = "王五";
drData[2] = "1";
dtData.Rows.Add(drData);
drData = dtData.NewRow();
drData[0] = 4;
drData[1] = "小芳";
drData[2] = "0";
dtData.Rows.Add(drData);
drData = dtData.NewRow();
drData[0] = 5;
drData[1] = "小娟";
drData[2] = "0";
dtData.Rows.Add(drData);
drData = dtData.NewRow();
drData[0] = 6;
drData[1] = "赵六";
drData[2] = "1";
dtData.Rows.Add(drData);
DataTable dt = new DataTable();
dt.Columns.Add("sexname");
dt.Columns.Add("sexvalue");
DataRow dr = dt.NewRow();
dr[0] = "男";
dr[1] = "1";
dt.Rows.Add(dr);
DataRow dr1 = dt.NewRow();
dr1[0] = "女";
dr1[1] = "0";
dt.Rows.Add(dr1);
this.tg.DataSource = dtData;
this.cb.DataSource = dt;
cb.ValueMember = "sexvalue";
cb.DisplayMember = "sexname";
}
private void cb_SelectedIndexChanged(object sender, EventArgs e)
{
string temp = this.cb.Text;
if (RowIndex < dtData.Rows.Count)
{
dtData.Rows[RowIndex][ColumnIndex] = temp;
}
}
private void dtp_TextChange(object sender, EventArgs e)
{
if (RowIndex < dtData.Rows.Count)
{
dtData.Rows[RowIndex][ColumnIndex] = dateTimePicker1.Text;
//时间控件选择时间时,就把时间赋给所在的单元格
}
}
private void OrderGrid_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
{
dateTimePicker1.Visible = false;
cb.Visible = false;
}
/***********滚动条滚动时,单元格位置发生变化,也得隐藏时间控件,不然时间控件位置不动就乱了********/
private void OrderGrid_Scroll(object sender, ScrollEventArgs e)
{
dateTimePicker1.Visible = false;
cb.Visible = false;
}
private void OrderGrid__CurrentCellChanged(object sender, EventArgs e)
{
try
{
if (tg.CurrentCell == null)
return;
if (tg.CurrentCell.ColumnIndex == 1)//判断是否指定列 在此指定和哪一列绑定
{
ColumnIndex = tg.CurrentCell.ColumnIndex;
RowIndex = tg.CurrentCell.ColumnIndex;
System.Drawing.Rectangle rect = tg.GetCellDisplayRectangle(tg.CurrentCell.ColumnIndex, tg.CurrentCell.RowIndex, true);
//得到所在单元格位置和大小
dateTimePicker1.Size = new Size(rect.Width, rect.Height);
//把单元格大小赋给时间控件
dateTimePicker1.Location = new Point(rect.X, rect.Y); //把单元格位置赋给时间控件
dateTimePicker1.Visible = true;
}
else if (tg.CurrentCell.ColumnIndex == 2)
{
ColumnIndex = tg.CurrentCell.ColumnIndex;
RowIndex = tg.CurrentCell.ColumnIndex;
System.Drawing.Rectangle rect = tg.GetCellDisplayRectangle(tg.CurrentCell.ColumnIndex, tg.CurrentCell.RowIndex, true);
//得到所在单元格位置和大小
cb.Size = new Size(rect.Width, rect.Height);
//把单元格大小赋给时间控件
cb.Location = new Point(rect.X, rect.Y); //把单元格位置赋给时间控件
cb.Visible = true;
}
else
{
dateTimePicker1.Visible = false;
cb.Visible = false;
}
}
catch
{
}
}
}