自定义单元格绘制组件DataGridViewCellPainter

来源:互联网 发布:淘宝中权重是什么意思 编辑:程序博客网 时间:2024/05/17 06:38

Author: Alex Leo; Email: mailto:alexleo321@hotmail.com; Blog: http://blog.csdn.net/ConExpress/

本示例演示如何在DataGridView的CellPainting事件中自定义单元格的绘制,实现自定义边框、背景和文本格式。边框可定义宽度、颜色以及绘制位置;背景可定义单色背景或图片背景;文本可定义字体、颜色、大小、对齐方式、截断方式等。

组件源码及示例代码:http://download.csdn.net/source/833346

 

示例效果如下:

绘制行标题和列标题,蓝色背景:

绘制行标题和内容,图像背景:

绘制列标题和内容,图像背景:

绘制行标题、列标题和内容,图像背景:

类图如下:

类详细信息:

 

组件的实现比较简单。首先添加一个DataGridView类型的属性TargetControl,设置该属性后指定控件CellPainting事件处理方法TargetControl_CellPainting,在其中实现自定义绘制。

  1.         private DataGridView m_TargetControl = null;
  2.         [Category(c_ControlCategory), Description("要编辑的目标 DataGridView 控件。"), DefaultValue(null)]
  3.         public DataGridView TargetControl
  4.         {
  5.             get { return m_TargetControl; }
  6.             set
  7.             {
  8.                 if (m_TargetControl != value)
  9.                 {
  10.                     if (m_TargetControl != null)
  11.                     {
  12.                         m_TargetControl.CellPainting -= new DataGridViewCellPaintingEventHandler(TargetControl_CellPainting);//移除之前的自定义绘制
  13.                         m_TargetControl.Refresh();
  14.                     }
  15.                     m_TargetControl = value;
  16.                     if (m_TargetControl != null)
  17.                     {
  18.                         TargetControl.CellPainting += new DataGridViewCellPaintingEventHandler(TargetControl_CellPainting);//设置自定义绘制方法
  19.                     }
  20.                     this.OnPropertyChanged("TargetControl");
  21.                 }
  22.             }
  23.         }

 

CellPainting方法中处理单元格的绘制:

  1.         void TargetControl_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
  2.         {
  3.             if (this.Container == null)//移除组件后移除自定义绘制
  4.             {
  5.                 this.m_TargetControl.CellPainting -= new DataGridViewCellPaintingEventHandler(TargetControl_CellPainting);
  6.                 this.m_TargetControl.Refresh();
  7.                 return;
  8.             }
  9.             if (this.m_Enable)
  10.             {
  11.                 bool blnDrawFlag = false;
  12.                 if (e.ColumnIndex < 0)//行标题
  13.                 {
  14.                     blnDrawFlag = ((e.RowIndex < 0) ? this.m_DrawHeaderCorner : this.m_DrawRowHeader);
  15.                 }
  16.                 else
  17.                 {
  18.                     blnDrawFlag = ((e.RowIndex < 0) ? this.m_DrawColumnHeader : this.m_DrawContentCell);
  19.                 }
  20.                 if (blnDrawFlag)//判断是否绘制当前单元格
  21.                 {
  22.                     //考虑加入事件,这样用户可以进行更灵活的控制
  23.                     this.DrawBackground(e);//绘制背景
  24.                     this.DrawBorder(e);//绘制边框
  25.                     this.DrawHeaderText(e);//绘制文本
  26.                     e.Handled = true;//标记为已处理
  27.                 }
  28.             }
  29.         }

 

这里把绘制背景,绘制边框和绘制文本分开处理,条理更清晰。

  1.         /// <summary>
  2.         /// 绘制背景
  3.         /// </summary>
  4.         /// <param name="e"></param>
  5.         private void DrawBackground(DataGridViewCellPaintingEventArgs e)
  6.         {
  7.             Brush BackBrush = null;
  8.             if (BackImage != null)//如果指定背景图片则用TextureBrush,否则用SolidBrush
  9.                 BackBrush = new TextureBrush(BackImage, m_WrapMode);
  10.             else
  11.                 BackBrush = new SolidBrush(BackColor);
  12.             e.Graphics.FillRectangle(BackBrush, e.CellBounds);//填充背景
  13.         }
  14.         /// <summary>
  15.         /// 绘制边框
  16.         /// </summary>
  17.         /// <param name="e"></param>
  18.         private void DrawBorder(DataGridViewCellPaintingEventArgs e)
  19.         {
  20.             //绘制边框
  21.             int intXLeft, intXRight, intYTop, intYBottom;
  22.             intXLeft = e.CellBounds.Location.X;
  23.             intXRight = e.CellBounds.Location.X + e.CellBounds.Width - 1;
  24.             intYTop = e.CellBounds.Location.Y;
  25.             intYBottom = e.CellBounds.Location.Y + e.CellBounds.Height - 1;
  26.             //用绘制矩形的方式绘制边框更容易控制
  27.             //绘制边框线条,上左右下的顺序
  28.             e.Graphics.FillRectangle(new SolidBrush(BorderTopColor), new Rectangle(e.CellBounds.Location, new Size(e.CellBounds.Width, BorderWidth)));//top
  29.             e.Graphics.FillRectangle(new SolidBrush(BorderLeftColor), new Rectangle(e.CellBounds.Location, new Size(BorderWidth, e.CellBounds.Height)));//left
  30.             e.Graphics.FillRectangle(new SolidBrush(BorderRightColor), new Rectangle(intXRight - BorderWidth + 1, intYTop, BorderWidth, e.CellBounds.Height));//right
  31.             e.Graphics.FillRectangle(new SolidBrush(BorderBottomColor), new Rectangle(intXLeft, intYBottom - BorderWidth + 1, e.CellBounds.Width, BorderWidth));//bottom
  32.         }
  33.         /// <summary>
  34.         /// 绘制标题文本
  35.         /// </summary>
  36.         /// <param name="e"></param>
  37.         private void DrawHeaderText(DataGridViewCellPaintingEventArgs e)
  38.         {
  39.             if (e.Value == null || e.Value == DBNull.Value || e.Value.ToString().Length == 0)
  40.                 return;
  41.             //设置文本格式
  42.             StringFormat myStringFormat = new StringFormat();
  43.             myStringFormat.Alignment = Align;//水平对齐方式
  44.             myStringFormat.LineAlignment = VAlign;//垂直对齐方式
  45.             myStringFormat.Trimming = TrimType;//截断方式
  46.             myStringFormat.FormatFlags = StringFormatFlags.DisplayFormatControl;
  47.             e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
  48.             e.Graphics.DrawString(e.Value.ToString(), m_Font, new SolidBrush(ForeColor), e.CellBounds, myStringFormat);//绘制文字
  49.         }

 

其他相关的属性就不在这里详细介绍,都是控制绘制方式的。可以根据需要添加相关的控制属性,比如四个边框的颜色都可以不一样,标题和内容的字体不一样,奇偶行的样式不一样等等,然后在绘制方法中相应调整就很容易实现了。注意在用背景图片的时候尽量采用小尺寸的图片,否则会影响绘制效率。

组件源码及示例代码:http://download.csdn.net/source/833346

原创粉丝点击