收集一些在DataGridVeiw使用技巧,备用。
一、DataGridView 单元格验证
1、定义单元格验证
要求:验证错误后焦点不离开。
实现:
单元格的验证可以使用dgv_details_CellValidating事件。
验证不通过时调用e.Cancel = true;终止事件链,单元格将保持编辑状态。
调用dgv_details.CancelEdit();可以使单元格的内容会滚到修改前的值。
使用System.Windows.Forms.SendKeys.Send("^a");将全选单元格的内容。
2、单元格选中并开始编辑状态
实现:
- //DataGridView获得焦点
- dgv_details.Focus();
- //DataGridView指定当前单元格
- dgv_details.CurrentCell = dgv_details[0, 0];
- //开始编辑状态
- dgv_details.BeginEdit(false);
3、定制自动生成绑定了列
实现:
- dgv_details.AutoGenerateColumns = false;
4、设置列的背景色
实现:
- Color GridReadOnlyColor = Color.LightGoldenrodYellow;
- dgv_details.Columns[1].DefaultCellStyle.BackColor = WinKeys.GridReadOnlyColor;
5、DataGridView单元格验证的设计的问题
问题:绑定还是不绑定?
1)绑定的优势:比较简单,代码少。
2)绑定得缺点:DataGridView中的数据受数据源的影响(主键约束、值类型约束)。不一至时会激发DataError事件,输入的内容无法保存到单元格中和数据源中。特殊的验证(比如长度、格式等)还是需要另外写代码实现。
关于增加行的问题。增加新行时多主键的验证有问题,而且验证不通过时会将新行全部删除。限制很多,很不方便。
3)非绑定的优势:验证等处理比较灵活。不受数据源的约束。
4)非绑定得缺点:显示和向数据库更新数据时需要比较多的代码实现,效率比较低。
5)总的感觉在处理验证比较麻烦的场合,我还是比较喜欢非绑定的方式。如果数据量大,验证比较简单的场合使用绑定模式比较好。
二、DataGridView重绘代码
1、CellFormatting事件,一般重绘单元格属性。
- private Bitmap highPriImage;
- private Bitmap mediumPriImage;
- private Bitmap lowPriImage;
- private void dataGridView1_CellFormatting(object sender,
- System.Windows.Forms.DataGridViewCellFormattingEventArgs e)
- {
- // Set the background to red for negative values in the Balance column.
- if (dataGridView1.Columns[e.ColumnIndex].Name.Equals("Balance"))
- {
- Int32 intValue;
- if (Int32.TryParse((String)e.Value, out intValue) &&
- (intValue < 0))
- {
- e.CellStyle.BackColor = Color.Red;
- e.CellStyle.SelectionBackColor = Color.DarkRed;
- }
- }
- // Replace string values in the Priority column with images.
- if (dataGridView1.Columns[e.ColumnIndex].Name.Equals("Priority"))
- {
- // Ensure that the value is a string.
- String stringValue = e.Value as string;
- if (stringValue == null) return;
- // Set the cell ToolTip to the text value.
- DataGridViewCell cell = dataGridView1[e.ColumnIndex, e.RowIndex];
- cell.ToolTipText = stringValue;
- // Replace the string value with the image value.
- switch (stringValue)
- {
- case "high":
- e.Value = highPriImage;
- break;
- case "medium":
- e.Value = mediumPriImage;
- break;
- case "low":
- e.Value = lowPriImage;
- break;
- }
- }
- }
2、CellPainting事件,一般用于合并单元格用
Windows Forms DataGridView 没有提供合并单元格的功能,要实现合并单元格的功能就要在CellPainting事件中使用Graphics.DrawLine和 Graphics.DrawString 自己来“画”。
下面的代码可以对DataGridView第1列内容相同的单元格进行合并:
- #region"合并单元格的测试"
- private int? nextrow = null;
- private int? nextcol = null;
- private void dataGridView1_CellFormatting(object sender, System.Windows.Forms.DataGridViewCellFormattingEventArgs e)
- {
- if (this.dataGridView1.Columns["description"].Index == e.ColumnIndex && e.RowIndex >= 0)
- {
- if (this.nextcol != null & e.ColumnIndex == this.nextcol)
- {
- e.CellStyle.BackColor = Color.LightBlue;
- this.nextcol = null;
- }
- if (this.nextrow != null & e.RowIndex == nextrow)
- {
- e.CellStyle.BackColor = Color.LightPink;
- this.nextrow = null;
- }
- if (e.RowIndex != this.dataGridView1.RowCount - 1)
- {
- if (e.Value.ToString() == this.dataGridView1.Rows[e.RowIndex + 1].Cells[e.ColumnIndex].Value.ToString())
- {
- e.CellStyle.BackColor = Color.LightPink;
- nextrow = e.RowIndex + 1;
- }
- }
- }
- if (this.dataGridView1.Columns["name"].Index == e.ColumnIndex && e.RowIndex >= 0)
- {
- if (e.Value.ToString() == this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex + 1].Value.ToString())
- {
- e.CellStyle.BackColor = Color.LightBlue;
- nextcol = e.ColumnIndex + 1;
- }
- }
- }
- //==========================
- //绘制单元格
- private void dataGridView1_CellPainting(object sender, System.Windows.Forms.DataGridViewCellPaintingEventArgs e)
- {
- //纵向合并
- if (this.dataGridView1.Columns["description"].Index == e.ColumnIndex && e.RowIndex >= 0)
- {
- using (
- Brush gridBrush = new SolidBrush(this.dataGridView1.GridColor),
- backColorBrush = new SolidBrush(e.CellStyle.BackColor))
- {
- using (Pen gridLinePen = new Pen(gridBrush))
- {
- // 擦除原单元格背景
- e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
- 绘制线条,这些线条是单元格相互间隔的区分线条,
- 因为我们只对列name做处理,所以datagridview自己会处理左侧和上边缘的线条
- if (e.RowIndex != this.dataGridView1.RowCount - 1)
- {
- if (e.Value.ToString() != this.dataGridView1.Rows[e.RowIndex + 1].Cells[e.ColumnIndex].Value.ToString())
- {
- e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1,
- e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);//下边缘的线
- //绘制值
- if (e.Value != null)
- {
- e.Graphics.DrawString((String)e.Value, e.CellStyle.Font,
- Brushes.Crimson, e.CellBounds.X + 2,
- e.CellBounds.Y + 2, StringFormat.GenericDefault);
- }
- }
- }
- else
- {
- e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1,
- e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);//下边缘的线
- //绘制值
- if (e.Value != null)
- {
- e.Graphics.DrawString((String)e.Value, e.CellStyle.Font,
- Brushes.Crimson, e.CellBounds.X + 2,
- e.CellBounds.Y + 2, StringFormat.GenericDefault);
- }
- }
- //右侧的线
- e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1,
- e.CellBounds.Top, e.CellBounds.Right - 1,
- e.CellBounds.Bottom - 1);
- e.Handled = true;
- }
- }
- }
- //横向合并
- if (this.dataGridView1.Columns["name"].Index == e.ColumnIndex && e.RowIndex >= 0)
- {
- using (
- Brush gridBrush = new SolidBrush(this.dataGridView1.GridColor),
- backColorBrush = new SolidBrush(e.CellStyle.BackColor))
- {
- using (Pen gridLinePen = new Pen(gridBrush))
- {
- // 擦除原单元格背景
- e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
- if (e.Value.ToString() != this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex + 1].Value.ToString())
- {
- //右侧的线
- e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1, e.CellBounds.Top,
- e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);
- //绘制值
- if (e.Value != null)
- {
- e.Graphics.DrawString((String)e.Value, e.CellStyle.Font,
- Brushes.Crimson, e.CellBounds.X + 2,
- e.CellBounds.Y + 2, StringFormat.GenericDefault);
- }
- }
- //下边缘的线
- e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1,
- e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);
- e.Handled = true;
- }
- }
- }
- }
- #endregion
三、在GridView中如何格式化Money型字段(downmoon)?
- DataMember="DefaultView" DataSourceID="SqlDataSource1">
- SortExpression="PKID" />
- amount
这段代码中,
amount为Money型字段,无论如何只能显示成
1234.5600
而不能显示成
1,234.56
用
也不行!
后来在MSDN上找到了答案
关键在于HtmlEncode="False"
http://blogs.msdn.com/danielfe/archive/2006/02/08/527628.aspx
(源文:http://blog.youkuaiyun.com/downmoon/archive/2007/11/01/1860611.aspx)
四、DataGridView合并单元格 编辑单元格
同事的一个项目需要将DataGridView单元格中的内容分不同颜色显示,想了想只有重绘了。
这种方法还可以用做合并单元格。
参考代码:
- private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
- {
- if (e.RowIndex == 0 && e.ColumnIndex >= 0)
- {
- int left = e.CellBounds.Left;
- int top = e.CellBounds.Top;
- int right = e.CellBounds.Right;
- int bottom = e.CellBounds.Bottom;
- e.Graphics.FillRectangle(new SolidBrush(Color.White), e.CellBounds);
- e.Handled = true;
- Brush gridBrush = new SolidBrush(this.dataGridView1.GridColor);
- Pen gridLinePen = new Pen(gridBrush);
- e.Graphics.DrawLine(gridLinePen, right - 1,
- top, right - 1,
- bottom - 1);
- e.Graphics.DrawLine(gridLinePen, left,
- bottom - 1, right,
- bottom - 1);
- Brush b1 = new SolidBrush(Color.Black);
- e.Graphics.DrawString((String)e.Value, e.CellStyle.Font,
- b1, left + 2,
- top + 1, StringFormat.GenericDefault);
- Brush b2 = new SolidBrush(Color.Red);
- e.Graphics.DrawString((String)e.Value, e.CellStyle.Font,
- b2, left + 2,
- top + 10, StringFormat.GenericDefault);
- }
- DataGridViewSelectedCellCollection dgvscc = this.dataGridView1.SelectedCells;
- foreach (DataGridViewCell dgvc in dgvscc)
- {
- if (e.RowIndex == 0
- && e.RowIndex == dgvc.RowIndex
- && e.ColumnIndex == dgvc.ColumnIndex)
- {
- int left = e.CellBounds.Left;
- int top = e.CellBounds.Top;
- int right = e.CellBounds.Right;
- int bottom = e.CellBounds.Bottom;
- // 绘制背景,覆盖单元格区域
- e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(10,36,106)), e.CellBounds);
- // 绘制边框
- Brush gridBrush = new SolidBrush(this.dataGridView1.GridColor);
- Pen gridLinePen = new Pen(gridBrush);
- e.Graphics.DrawLine(gridLinePen, right - 1,
- top, right - 1,
- bottom - 1);
- e.Graphics.DrawLine(gridLinePen, left,
- bottom - 1, right,
- bottom - 1);
- // 绘制文字
- Brush b1 = new SolidBrush(Color.White);
- e.Graphics.DrawString((String)e.Value, e.CellStyle.Font,
- b1, left + 2,
- top + 1, StringFormat.GenericDefault);
- Brush b2 = new SolidBrush(Color.White);
- e.Graphics.DrawString((String)e.Value, e.CellStyle.Font,
- b2, left + 2,
- top + 10, StringFormat.GenericDefault);
- }
- }
- e.Handled = true;
- }
感谢各位作者。