关闭

DataGridView使用技巧(集)

789人阅读 评论(0) 收藏 举报

一、DataGridView 单元格验证

1、定义单元格验证
要求:
验证错误后焦点不离开。
实现:
单元格的验证可以使用dgv_details_CellValidating事件。
验证不通过时调用e.Cancel = true;终止事件链,单元格将保持编辑状态。
调用dgv_details.CancelEdit();可以使单元格的内容会滚到修改前的值。
使用System.Windows.Forms.SendKeys.Send("^a");将全选单元格的内容。

2、单元格选中并开始编辑状态
实现:

  1. //DataGridView获得焦点
  2. dgv_details.Focus();
  3. //DataGridView指定当前单元格
  4. dgv_details.CurrentCell = dgv_details[0, 0];
  5. //开始编辑状态
  6. dgv_details.BeginEdit(false);

3、定制自动生成绑定了列
实现:

  1. dgv_details.AutoGenerateColumns = false;

4、设置列的背景色
实现:

  1. Color GridReadOnlyColor = Color.LightGoldenrodYellow;
  2. dgv_details.Columns[1].DefaultCellStyle.BackColor = WinKeys.GridReadOnlyColor;

5、DataGridView单元格验证的设计的问题
问题:绑定还是不绑定?
1)绑定的优势:比较简单,代码少。
2)绑定得缺点:DataGridView中的数据受数据源的影响(主键约束、值类型约束)。不一至时会激发DataError事件,输入的内容无法保存到单元格中和数据源中。特殊的验证(比如长度、格式等)还是需要另外写代码实现。
关于增加行的问题。增加新行时多主键的验证有问题,而且验证不通过时会将新行全部删除。限制很多,很不方便。
3)非绑定的优势:验证等处理比较灵活。不受数据源的约束。
4)非绑定得缺点:显示和向数据库更新数据时需要比较多的代码实现,效率比较低。
5)总的感觉在处理验证比较麻烦的场合,我还是比较喜欢非绑定的方式。如果数据量大,验证比较简单的场合使用绑定模式比较好。

二、DataGridView重绘代码

1、CellFormatting事件,一般重绘单元格属性。

  1.    private Bitmap highPriImage;
  2.     private Bitmap mediumPriImage;
  3.     private Bitmap lowPriImage;
  4. private void dataGridView1_CellFormatting(object sender, 
  5.         System.Windows.Forms.DataGridViewCellFormattingEventArgs e)
  6.     {
  7.         // Set the background to red for negative values in the Balance column.
  8.         if (dataGridView1.Columns[e.ColumnIndex].Name.Equals("Balance"))
  9.         {
  10.             Int32 intValue;
  11.             if (Int32.TryParse((String)e.Value, out intValue) && 
  12.                 (intValue < 0))
  13.             {
  14.                 e.CellStyle.BackColor = Color.Red;
  15.                 e.CellStyle.SelectionBackColor = Color.DarkRed;
  16.             }
  17.         }
  18.         // Replace string values in the Priority column with images.
  19.         if (dataGridView1.Columns[e.ColumnIndex].Name.Equals("Priority"))
  20.         {
  21.             // Ensure that the value is a string.
  22.             String stringValue = e.Value as string;
  23.             if (stringValue == nullreturn;
  24.             // Set the cell ToolTip to the text value.
  25.             DataGridViewCell cell = dataGridView1[e.ColumnIndex, e.RowIndex];
  26.             cell.ToolTipText = stringValue;
  27.             // Replace the string value with the image value.
  28.             switch (stringValue)
  29.             {
  30.                 case "high":
  31.                     e.Value = highPriImage;
  32.                     break;
  33.                 case "medium":
  34.                     e.Value = mediumPriImage;
  35.                     break;
  36.                 case "low":
  37.                     e.Value = lowPriImage;
  38.                     break;
  39.             }
  40.         }
  41.     }

2、CellPainting事件,一般用于合并单元格用
Windows Forms DataGridView 没有提供合并单元格的功能,要实现合并单元格的功能就要在CellPainting事件中使用Graphics.DrawLine和 Graphics.DrawString 自己来“画”。
下面的代码可以对DataGridView第1列内容相同的单元格进行合并:

  1. #region"合并单元格的测试"
  2. private int? nextrow = null;
  3. private int? nextcol = null;
  4. private void dataGridView1_CellFormatting(object sender, System.Windows.Forms.DataGridViewCellFormattingEventArgs e)
  5. {
  6.     if (this.dataGridView1.Columns["description"].Index == e.ColumnIndex && e.RowIndex >= 0)
  7.     {
  8.         if (this.nextcol != null & e.ColumnIndex == this.nextcol)
  9.         {
  10.             e.CellStyle.BackColor = Color.LightBlue;
  11.             this.nextcol = null;
  12.         }
  13.         if (this.nextrow != null & e.RowIndex == nextrow)
  14.         {
  15.             e.CellStyle.BackColor = Color.LightPink;
  16.             this.nextrow = null;
  17.         }
  18.         if (e.RowIndex != this.dataGridView1.RowCount - 1)
  19.         {
  20.             if (e.Value.ToString() == this.dataGridView1.Rows[e.RowIndex + 1].Cells[e.ColumnIndex].Value.ToString())
  21.             {
  22.                 e.CellStyle.BackColor = Color.LightPink;
  23.                 nextrow = e.RowIndex + 1;
  24.             }
  25.         } 
  26.     }
  27.     if (this.dataGridView1.Columns["name"].Index == e.ColumnIndex && e.RowIndex >= 0)
  28.     {
  29.         if (e.Value.ToString() == this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex + 1].Value.ToString())
  30.         {
  31.             e.CellStyle.BackColor = Color.LightBlue;
  32.             nextcol = e.ColumnIndex + 1;
  33.         }
  34.     }
  35. }
  36. //==========================
  37.        
  38. //绘制单元格
  39. private void dataGridView1_CellPainting(object sender, System.Windows.Forms.DataGridViewCellPaintingEventArgs e)
  40. {
  41.     //纵向合并
  42.     if (this.dataGridView1.Columns["description"].Index == e.ColumnIndex && e.RowIndex >= 0)
  43.     {
  44.         using (
  45.             Brush gridBrush = new SolidBrush(this.dataGridView1.GridColor),
  46.             backColorBrush = new SolidBrush(e.CellStyle.BackColor))
  47.         {
  48.             using (Pen gridLinePen = new Pen(gridBrush))
  49.             {
  50.                 // 擦除原单元格背景
  51.                 e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
  52.                 ////绘制线条,这些线条是单元格相互间隔的区分线条,
  53.                 ////因为我们只对列name做处理,所以datagridview自己会处理左侧和上边缘的线条
  54.                 if (e.RowIndex != this.dataGridView1.RowCount - 1)
  55.                 {
  56.                     if (e.Value.ToString() != this.dataGridView1.Rows[e.RowIndex + 1].Cells[e.ColumnIndex].Value.ToString())
  57.                     {
  58.                         e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1,
  59.                         e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);//下边缘的线
  60.                         //绘制值
  61.                         if (e.Value != null)
  62.                         {
  63.                             e.Graphics.DrawString((String)e.Value, e.CellStyle.Font,
  64.                                 Brushes.Crimson, e.CellBounds.X + 2,
  65.                                 e.CellBounds.Y + 2, StringFormat.GenericDefault);
  66.                         }
  67.                     }
  68.                 }
  69.                 else
  70.                 {
  71.                     e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1,
  72.                         e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);//下边缘的线
  73.                     //绘制值
  74.                     if (e.Value != null)
  75.                     {
  76.                         e.Graphics.DrawString((String)e.Value, e.CellStyle.Font,
  77.                             Brushes.Crimson, e.CellBounds.X + 2,
  78.                             e.CellBounds.Y + 2, StringFormat.GenericDefault);
  79.                     }
  80.                 }
  81.                 //右侧的线
  82.                 e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1,
  83.                     e.CellBounds.Top, e.CellBounds.Right - 1,
  84.                     e.CellBounds.Bottom - 1);
  85.                 e.Handled = true;
  86.             }
  87.         }
  88.     }
  89.     //横向合并
  90.     if (this.dataGridView1.Columns["name"].Index == e.ColumnIndex && e.RowIndex >= 0)
  91.     {
  92.         using (
  93.             Brush gridBrush = new SolidBrush(this.dataGridView1.GridColor),
  94.             backColorBrush = new SolidBrush(e.CellStyle.BackColor))
  95.         {
  96.             using (Pen gridLinePen = new Pen(gridBrush))
  97.             {
  98.                 // 擦除原单元格背景
  99.                 e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
  100.                 if (e.Value.ToString() != this.dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex + 1].Value.ToString())
  101.                 {
  102.                     //右侧的线
  103.                     e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1, e.CellBounds.Top,
  104.                         e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);
  105.                     //绘制值
  106.                     if (e.Value != null)
  107.                     {
  108.                         e.Graphics.DrawString((String)e.Value, e.CellStyle.Font,
  109.                             Brushes.Crimson, e.CellBounds.X + 2,
  110.                             e.CellBounds.Y + 2, StringFormat.GenericDefault);
  111.                     }
  112.                 }
  113.                 //下边缘的线
  114.                 e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1,
  115.                                             e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);
  116.                 e.Handled = true;
  117.             }
  118.         }
  119.     }
  120. }
  121. #endregion

三、在GridView中如何格式化Money型字段(downmoon)?

  1.         <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="PKID"
  2.             DataMember="DefaultView" DataSourceID="SqlDataSource1">
  3.             <Columns>
  4.                 <asp:BoundField DataField="PKID" HeaderText="PKID" InsertVisible="False" ReadOnly="True"
  5.                     SortExpression="PKID" />
  6.                 
  7.                 <asp:TemplateField>
  8.                         <HeaderTemplate>
  9.                            amount</HeaderTemplate>
  10.                         <ItemTemplate>
  11.                             <asp:Label ID="txtMoney" Text='<%# Decimal.Parse(DataBinder.Eval(Container.DataItem,"amount").ToString())%>' runat="server" />
  12.                         </ItemTemplate>
  13.                     </asp:TemplateField>
  14.                 <asp:BoundField DataField="TestID" HeaderText="TestID" SortExpression="TestID" />
  15.                 <asp:BoundField DataField="testString" HeaderText="testString" SortExpression="testString" />
  16.             </Columns>
  17.         </asp:GridView>

这段代码中,
amount为Money型字段,无论如何只能显示成
1234.5600  
而不能显示成
1,234.56

  1. <asp:BoundField DataField="amount" HeaderText="amount" DataFormatString="{0:n2}"  />
  2.                    <asp:BoundField DataField="amount" HeaderText="amount" DataFormatString="{0:c2}"  />

也不行!
后来在MSDN上找到了答案

  1. <asp:BoundField DataField="amount" HeaderText="amount" DataFormatString="{0:#,###.00}"  HtmlEncode="False" />

关键在于HtmlEncode="False"

http://blogs.msdn.com/danielfe/archive/2006/02/08/527628.aspx

(源文:http://blog.csdn.net/downmoon/archive/2007/11/01/1860611.aspx

四、DataGridView合并单元格 编辑单元格

同事的一个项目需要将DataGridView单元格中的内容分不同颜色显示,想了想只有重绘了。
这种方法还可以用做合并单元格。

参考代码:

  1. private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
  2.         {
  3.             if (e.RowIndex == 0 && e.ColumnIndex >= 0)
  4.             {
  5.                 int left = e.CellBounds.Left;
  6.                 int top = e.CellBounds.Top;
  7.                 int right = e.CellBounds.Right;
  8.                 int bottom = e.CellBounds.Bottom;
  9.                 e.Graphics.FillRectangle(new SolidBrush(Color.White), e.CellBounds);
  10.                 e.Handled = true;
  11.                 Brush gridBrush = new SolidBrush(this.dataGridView1.GridColor);
  12.                 Pen gridLinePen = new Pen(gridBrush);
  13.                 e.Graphics.DrawLine(gridLinePen, right - 1,
  14.                            top, right - 1,
  15.                            bottom - 1);
  16.                 e.Graphics.DrawLine(gridLinePen, left,
  17.                            bottom - 1, right,
  18.                            bottom - 1); 
  19.                 Brush b1 = new SolidBrush(Color.Black);
  20.                 e.Graphics.DrawString((String)e.Value, e.CellStyle.Font,
  21.                                         b1, left + 2,
  22.                                         top + 1, StringFormat.GenericDefault); 
  23.                 Brush b2 = new SolidBrush(Color.Red);
  24.                 e.Graphics.DrawString((String)e.Value, e.CellStyle.Font,
  25.                                         b2, left + 2,
  26.                                         top + 10, StringFormat.GenericDefault);
  27.             } 
  28.             DataGridViewSelectedCellCollection dgvscc = this.dataGridView1.SelectedCells;
  29.             foreach (DataGridViewCell dgvc in dgvscc)
  30.             {
  31.                     if (e.RowIndex == 0 
  32.                         && e.RowIndex == dgvc.RowIndex 
  33.                         && e.ColumnIndex == dgvc.ColumnIndex)
  34.                     {
  35.                         int left = e.CellBounds.Left;
  36.                         int top = e.CellBounds.Top;
  37.                         int right = e.CellBounds.Right;
  38.                         int bottom = e.CellBounds.Bottom;
  39.                         // 绘制背景,覆盖单元格区域
  40.                         e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(10,36,106)), e.CellBounds);
  41.                         
  42.                         // 绘制边框
  43.                         Brush gridBrush = new SolidBrush(this.dataGridView1.GridColor);
  44.                         Pen gridLinePen = new Pen(gridBrush);
  45.                         e.Graphics.DrawLine(gridLinePen, right - 1,
  46.                                    top, right - 1,
  47.                                    bottom - 1);
  48.                         e.Graphics.DrawLine(gridLinePen, left,
  49.                                    bottom - 1, right,
  50.                                    bottom - 1); 
  51.                         // 绘制文字
  52.                         Brush b1 = new SolidBrush(Color.White);
  53.                         e.Graphics.DrawString((String)e.Value, e.CellStyle.Font,
  54.                                                 b1, left + 2,
  55.                                                 top + 1, StringFormat.GenericDefault); 
  56.                         Brush b2 = new SolidBrush(Color.White);
  57.                         e.Graphics.DrawString((String)e.Value, e.CellStyle.Font,
  58.                                                 b2, left + 2,
  59.                                                 top + 10, StringFormat.GenericDefault);
  60.                     }
  61.             } 
  62.             e.Handled = true;            
  63.         }

感谢各位作者。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:418437次
    • 积分:6115
    • 等级:
    • 排名:第4079名
    • 原创:230篇
    • 转载:48篇
    • 译文:8篇
    • 评论:36条
    博客专栏
    最新评论