DataGridView 的使用总结
一、属性应用
1.设置单元格鼠标点击后就进入编辑状态
设置DataGridView控件的EditMode这个属性,即
EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnEnter
这样当鼠标点击单元格时就会变成编辑状态。
2.设置DataGridView控件的行选择样式
设置DataGridView控件的SelectionMode这个属性,即
SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect
这样我们再选中的时候就是以行的形式选中的。
3.当用户点击列标题时不进行排序
在默认情况下,当用户点击DataGridView控件的列标题时会自动对内容进行排序,现在我们禁止它进行排序,通过设置每一列的SortMode这个属性来实现,即
SortMode=NotSortable
这样当我们点击列标题时就不会自动进行排序了。
4.去除DataGridView自带的一行(带有*号的那一行,或者是不允许用户添加数据)
DataGridView控件在默认的情况下会自动的绑上一行空数据,这一行空数据可以使用户进行数据添加,现在我们想去除这一列,通过设置属性
AllowUserToAddRows=false;
这样在绑定的时候就不会再显示这一行了。
5.设置单元格不可编辑
方法一:我们可以在控件完成数据绑定后在对DataGridView控件进行遍历,根据条件设置单元格的readonly属性,使此单元格不能进行编辑。如下:
/// <summary> /// 更新数据 /// </summary> public void UpdateData() { //获取数据源 dgvliucycx.DataSource = bll_liucy.GetAllList().Tables[0].DefaultView; //改变废弃项的背景颜色 ChangeColor(); //设置修改时间和修改人列为只读的 BandColumn(); } /// <summary> /// 改变DataGridView控件废弃项的背景颜色 /// </summary> public void ChangeColor() { //将已废弃的样品记录背景色表示为蓝色 try { for (int i = 0; i < dgvliucycx.Rows.Count; i++) { if (Convert.ToString(dgvliucycx.Rows[i].Cells["BIAOS"].Value) == "废弃") { dgvliucycx.Rows[i].DefaultCellStyle.BackColor = Color.Aqua; } } } catch (Exception ex) { KryptonMessageBox.Show(ex.ToString()); } }
/// <summary> /// 绑定修改人和修改时间这一列,进攻参考 /// </summary> public void BandColumn() { foreach (DataGridViewRow item in this.dgvliucycx.Rows) { //设定修改人和修改日期、标识为只读的 item.Cells["XIUGR"].ReadOnly = true; item.Cells["XIUGRQ"].ReadOnly = true; item.Cells["BIAOS"].ReadOnly = true; } } |
方法二:我们还可以在CellBeginEdit事件中进行判断是否对单元格进行编辑,如下:
// CellBeginEdit 事件处理方法 private void DataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) { DataGridView dgv = (DataGridView)sender; //是否可以进行编辑的条件检查 if (dgv.Columns[e.ColumnIndex].Name == "Column1" && !(bool)dgv["Column2", e.RowIndex].Value) { // 取消编辑 e.Cancel = true; } } |
6.DataGridView判断新增行
DataGridView的AllowUserToAddRows属性为True时也就是允许用户追加新行的场合下, DataGridView的最后一行就是新追加的
行(*行)。使用 DataGridViewRow.IsNewRow 属性可以判断哪一行是新追加的行。另外,通过DataGridView.NewRowIndex 可以
获取新行的行序列号。在没有新行的时候,NewRowIndex = -1。
7.DataGridView行删除操作的自定义
1) 无条件的限制行删除操作。
默认时,DataGridView 是允许用户进行行的删除操作的。如果设置 DataGridView对象的AllowUserToDeleteRows属性为 False 时, 用户的行删除操作就被禁止了。
但是,通过 DataGridViewRowCollection.Remove 还是可以进行行的删除。
补足: 如果 DataGridView 绑定的是 DataView 的话,通过 DataView.AllowDelete 也可以控制行的删除。
2) 行删除时的条件判断处理。
用户在删除行的时候,将会引发 DataGridView.UserDeletingRow 事件。 在这个事件里,可以判断条件并取消删除操作。
// DataGridView1 的 UserDeletingRow 事件
private void DataGridView1_UserDeletingRow(
object sender, DataGridViewRowCancelEventArgs e)
{
// 删除前的用户确认。
if (MessageBox.Show("确认要删除该行数据吗?", "删除确认",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Question) != DialogResult.OK)
{
// 如果不是 OK,则取消。
e.Cancel = true;
}
}
8.DataGridView行头和列头的隐藏
// 列头隐藏
DataGridView1.ColumnHeadersVisible = false;
// 行头隐藏
DataGridView1.RowHeadersVisible = false;
10.DataGridView行和列的删除
' 删除名为"Column1"的列
DataGridView1.Columns.Remove("Column1");
' 删除第一列
DataGridView1.Columns.RemoveAt(0);
' 删除第一行
DataGridView1.Rows.RemoveAt(0);
11.设置行或列为只读的
上面已经写过设置单元格只读,现在说一下行或列为只读的。
1)设置列只读
可以通过设计器直接在设计器中设置DataGridView中的某一列为只读,即用户在点击控件时不能使控件进入编辑状态,我们只需设置列属性Readonly=true即可,如下:
这样当给DataGridView控件绑定数据后,ID这一列就是不可编辑的。
2)设置行只读
设置行只读,在这里是通过编程的方式实现,在我们绑定完数据源后,在对DataGridView控件里面的数据行设置为只读,这时我们也可以根据我们自己程序的需要,设置要对哪些行设置只读,如下:
/// <summary> /// 设置行只读 /// </summary> public void SetReadonlyRow() { //遍历DataGridView控件中所有的行,并将其设为只读,用户不可编辑 foreach (DataGridViewRow item in this.dgvFenxzgl.Rows) { //将行设置为只读,在这里我们可以写自己的条件控制哪些行需要只读 item.ReadOnly = true; } } |
12.使窗体在屏幕中间显示
设置窗体的StartPosition属性,如下:
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;//this表示的是窗体对象
13.设置窗体不可改变大小
设置窗体不可改变大小即设置窗体的最大大小和最小大小相同即可,即设置窗体的MaximumSize属性和MinimumSize属性相等,如下:
this.MaximumSize = new System.Drawing.Size(960, 620);//this表示的是窗体对象
this.MinimumSize = new System.Drawing.Size(960, 620);
14.不显示DataGridView下面的新行
在绑定数据后,DataGridView控件下面会默认添加一条新行(前面行头以*号打头的),这样的目的是为了使用户能在这里添加数据,有时为了美观,希望在绑定的时候不显示该行,而是通过按钮的形式进行添加,实现方法,我们只需设置DataGridView控件的AllowUserToAddRows属性,如下:
this.dgvFenxzgl.AllowUserToAddRows = false;
15.设置DataGridView控件中单元格的选中样式
默认情况下我们点击DataGridView控件时只是被单击的单元格选中状态,有时我们希望点击某个单元格将这一行数据全部选中或是某一列全部选中,这时就设置DataGridView控件的SelectionMode这个属性,如下:
//以单元格的形式选中 this.dgvFenxzgl.SelectionMode = DataGridViewSelectionMode.CellSelect;
//选中当前单元格的列头,如果DataGridView中某列设置了SortMode属性为Automatic,则不能将SelectionMode属性设置为ColumnHeaderSelect this.dgvFenxzgl.SelectionMode = DataGridViewSelectionMode.ColumnHeaderSelect;
//通过单击列的标头或该列所包含的单元格选定整个列。如果DataGridView中某列设置了SortMode属性为Automatic,则不能将SelectionMode属性设置为ColumnHeaderSelect this.dgvFenxzgl.SelectionMode = DataGridViewSelectionMode.FullColumnSelect;
//通过单击行的标头或是该行所包含的单元格选定整个行。 this.dgvFenxzgl.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
//通过单击行的标头单元格选定此行。通过单击某个单元格可以单独选定此单元格。 this.dgvFenxzgl.SelectionMode = DataGridViewSelectionMode.RowHeaderSelect; |
16.设置DataGridView控件中是否可以进行多选
在默认情况下,当我们按住Ctrl键时选中DataGridView中的数据行就可以进行多选,相关设置如下:
this.dgvFenxzgl.MultiSelect = true;//当设置为true时表示可以对数据行进行多选
17.禁用点击列标题进行排序
默认情况下,当我们点击DataGridView控件的列标题时会导致控件里面的数据进行重新排序,我们可以通过设置每一个列的SortMode属性来控制它的排序方式,如下:
//无排序,即点击列标题时不会导致数据重新排序 this.dgvFenxzgl.Columns["MEIKMC"].SortMode = DataGridViewColumnSortMode.NotSortable;
//点击列标题时会导致数据进行重排序 this.dgvFenxzgl.Columns["MEIKMC"].SortMode = DataGridViewColumnSortMode.Automatic;
//此列仅能以编程方式进行排序,并且列标头将包含排序标志符号的空间。 this.dgvFenxzgl.Columns["MEIKMC"].SortMode = DataGridViewColumnSortMode.Programmatic; |
18.DataGridView冻结列和行
冻结DataGridView的列和行,通过设置属性Frozen来进行控制。
1)冻结列
冻结列我们可以再设置器中进行设置,如下:
2)冻结行
冻结行的时候我们就需通过编程的方式实现,方法如下:
/// <summary> /// 冻结行或列 /// </summary> public void FrozenRowOrColumn() { //冻结行 foreach (DataGridViewRow item in this.dgvFenxzgl.Rows) { item.Frozen = true; }
//冻结列 foreach (DataGridViewColumn item in this.dgvFenxzgl.Columns) { item.Frozen = true; } } |
二、事件应用
1.怎么样通过按钮事件给DataGridView控件添加一行空数据
我们希望我们通过按钮事件给DataGridView控件添加一行空数据,当我们点击按钮时,在Click事件中填写代码,如下:
DataRow newrow = ((DataView)(this.dgvliucycx.DataSource)).Table.DataSet.Tables[0].Rows.Add();
//设置默认值
newrow["DENGJRQ"] = DateTime.Now.ToLongDateString();
newrow["YOUXRQ"] = DateTime.Now.ToLongDateString();
newrow["BIAOS"] = "存储";
通过返回创建的新行对象,我们还可以为新添加的行设置默认值。
2.判断鼠标点中的行是否可以进行编辑
当用户点击某单元格想要修改它的数据的时候,需要做一个判断看看用户是否可以进行修改,解决办法是:当用户点中某一行时,会触发DataGridView控件CellBeginEdit事件,在这个事件里面我们可以根据用户点击的该行的数据来判断用户是否可以更改该行的数据。如下:
上面显示的是效果图,需求是这样的,当某条记录的状态时废弃时用户就不能在对其进行编辑,反之如果某条记录的状态是存储时,用户就可以对这条记录进行修改。实现:
//开始编辑单元格之前的判断
private void dgvliucycx_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
if (this.dgvliucycx.Rows[e.RowIndex].Cells["BIAOS"].Value.ToString().Equals("废弃"))
{
//取消对此单元格的编辑
e.Cancel = true;
return;
}
}
3.用户点击某单元格进行编辑时,触发事件的顺序及使用
首先触发的是CellBeginEdit事件----其次是CellParsing事件----再是CellEndEdit事件
CellBeginEdit事件:在触发该事件时单元格还没有获得焦点,我们可以通过设置事件参数e来决定是否执行对单元格的编辑,如下:
private void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
//执行编辑,这个一般不用写
e.Cancel = true;
//不执行编辑,这个一般是通过条件判断是否执行编辑,如果条件不成立,即不允许对单元格进行编辑
e.Cancel = false;
}
CellParsing事件:在该事件中我们可以对输入的文本进行格式化,如将输入的英文字母全部改成大写等等,如下;
private void dataGridView1_CellParsing(object sender, DataGridViewCellParsingEventArgs e)
{
/*
* 这里必须是通过e.Value来获得重新输入的值
* 如果是通过this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString()这种方法获得
* 那么获得值将是原来的值,并不是用户刚刚输入的值
* 这个也正可以对用户输入的数据进行验证,如果不符合则将原来的值再赋给该单元格,不进行修改
* 切记!!!!!
* 在这里必须将e.ParsingApplied属性设置为true,否则刚刚用户输入的值不会更新
* 还是会将原来的值赋给该单元格
* */
e.Value = e.Value.ToString().ToUpper();
e.ParsingApplied = true;
//MessageBox.Show(this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString());
}
CellEndEdit事件:触发该事件的时候,单元格已经失去焦点,可以获得更新后的值,如下:
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
//MessageBox.Show("CellEndEdit");
if (this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString().Contains("我"))
{
MessageBox.Show("有我" + "..." + this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString());
}
}
4.给新增行设置默认数据
前面已经讲过怎么通过按钮事件给DataGridView添加一个新行,现在我们给添加的新行设置默认值,如下:
private void button1_Click(object sender, EventArgs e)
{
DataRow newrow = ((DataView)(this.dataGridView1.DataSource)).Table.DataSet.Tables[0].Rows.Add();
newrow["StuID"] = "admin";
newrow["Name"] = "admin";
}
5.当我们点击DataGridView控件的列标题时触发的事件解释
会触发控件的ColumnHeaderMouseClick事件和ColumnHeaderMouseClick事件,在这里我们可以控制绑定数据的变化,如:
我们可以设置用户不在对绑定的数据进行编辑。
//当用户点击列标题时触发的事件 private void dgvFenxzgl_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) { //设置列不可编辑 SetReadonlyRow(); }
/// <summary> /// 设置行只读 /// </summary> public void SetReadonlyRow() { foreach (DataGridViewRow item in this.dgvFenxzgl.Rows) { item.ReadOnly = true; } } |
6.在DataGridView控件中编辑数据时检测输入数据的格式是否正确
在默认情况下,当我们对DataGridView控件里面的数据进行编辑时,如果我们输入的数据格式与绑定的数据源的格式不正确,就会引发异常,并触发DataGridView控件的DataError事件,在这个事件中通过事件参数e我们可以获得刚刚数据的数据,并且可以获得异常信息,同时我们也可以通过e.Cancel这个属性来决定是否取消事件的值。如下:
当我们在结果值这一栏中输入汉字时,就会引发异常,此时通过在DataError事件中我们就可以获取到该异常,将异常信息弹出,提示用户。方法如下:
//当输入的数据引发异常时执行的事件
private void dgvFenxzgl_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
KryptonMessageBox.Show(e.Exception.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
e.Cancel = true;
}
7.将新插入的行插入到DataGridView中的第一行的方法
这里我采用的是将数据源取出再放回的方法,如下:
//添加事件 private void btntj_Click(object sender, EventArgs e) { try { DataTable dt = ((DataView)dgvFenxzgl.DataSource).Table.DataSet.Tables[0]; DataRow dr = dt.NewRow(); dr["ZHI"] = "0"; dt.Rows.InsertAt(dr, 0); this.dgvFenxzgl.DataSource = dt.DefaultView; } catch (Exception ex) { MessageBox.Show(ex.Message); } } |
8.当用户点击Del(删除键)删除某一行时引发的事件
一般情况下我们不希望用户点击del删除键删除记录,这样可以设置DataGridView控件的AllowUserToDeleteRows属性控制用户是否可以删除行,如下:
//不允许用户点击键盘上的Del键删除数据 this.dgvFenxzgl.AllowUserToDeleteRows = false; //允许用户点击键盘上的Del键删除数据 this.dgvFenxzgl.AllowUserToDeleteRows = true; |
当用户点击键盘上的Del键删除数据时,会触发控件的UserDeletingRow事件,在事件里面我们进行我们的判断,如下:
//当用户点击键盘上的Del键删除数据时触发的事件 private void dgvFenxzgl_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e) { if (MessageBox.Show("您确定要删除该行吗?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK) { //确定要删除执行的操作 //在这里我们也可以通过e.Row这个属性获得要删除行的数据 //判断是否应该删除该行,还是用户操作失误 } else { //取消删除操作 e.Cancel = false; } } |
当行删除后会触发UserDeletedRow事件,如下:
//当删除结束时触发该事件 private void dgvFenxzgl_UserDeletedRow(object sender, DataGridViewRowEventArgs e) { MessageBox.Show("删除结束", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); } |
三、技巧应用
1.判断绑定到DataGridView中的数据是否被修改了
这里面绑定到DataGridView中数据源必须是DataTable或DataView,对于其他的数据源本方法未测试,在判断是否发生了改变的时候,我们需要将数据源取出,并强制转化为DataTable或DataView,如下:
//首先将绑定的数据源强制转化为数据表DataTable DataTable dt = ((DataView)(this.dgvFenxzgl.DataSource)).Table.DataSet.Tables[0]; //获得表中被修改的数据 DataTable dtModified = dt.GetChanges(DataRowState.Modified); if (dtModified.Rows.Count > 0)//如果行数大于0.表示已经有数据被修改了 { //在这里我们可以获得被修改的数据 //获得被修改的数据 foreach (DataRow item in dtModified.Rows) { //根据表结构获得它每行每列的值 /* * item["MEIKMC"].ToString(); * ... */ } } |
2.如何判断DataGridView中的新增行
这里绑定到DataGridView控件的数据源必须是DataTable或DataView,方法如下:
//首先将绑定的数据源强制转化为数据表DataTable DataTable dt = ((DataView)(this.dgvFenxzgl.DataSource)).Table.DataSet.Tables[0]; //获得表中新增的行数据 DataTable dtAdd = dt.GetChanges(DataRowState.Added); if (dtAdd.Rows.Count > 0)//如果行数大于0,表示已经有新行加入 { //在这里我们就可以获取新增行的数据 //获取新增行数据的方法 foreach (DataRow item in dtAdd.Rows) { //根据表结构获得它每行每列的值 /* * item["MEIKMC"].ToString(); * ... */ } } |
3.设置DataGridView控件的各行变色
在绑定完数据后,进行如下操作,方法如下:
/// <summary> /// 设置各行变色 /// </summary> public void SetRowBgColor() { foreach (DataGridViewRow item in this.dgvFenxzgl.Rows) { if (item.Index % 2 == 0) { item.DefaultCellStyle.BackColor = Color.Aqua; } else { item.DefaultCellStyle.BackColor = Color.DarkGray; } } } |
4.设置选中行的背景色
在绑定完数据源完,执行下面的操作,方法如下:
/// <summary> /// 设置选中行的背景色 /// </summary> public void SetSelectedRowBgColor() { foreach (DataGridViewRow item in this.dgvFenxzgl.Rows) { //设置选中行的背景色 item.DefaultCellStyle.SelectionBackColor = Color.DarkRed; //设置选中行的前景色 item.DefaultCellStyle.SelectionForeColor = Color.DarkSeaGreen; } } |