借鉴别人的,改了改,没用timer
using System;
using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.Runtime.InteropServices;using System.Drawing.Design;namespace Salem.Library.Control.DataGridView
{ /// <summary> /// 拥有默认样式带合并表头功能的DataGridView /// </summary> public partial class DataGridViewEx : System.Windows.Forms.DataGridView { #region 字段属性//是否显示行号
private bool showNum = false; /// <summary> /// 是否显示行号 /// </summary> [DefaultValue(true), Description("是否显示行号")] public bool ShowNum { get { return showNum; } set { showNum = value; if (value) { this.RowHeadersVisible = true; } } }private Dictionary<int, SpanInfo> SpanRows = new Dictionary<int, SpanInfo>();
private List<string> _mergecolumnname = new List<string>();
/// <summary> /// 合并列的名称 /// </summary> [MergableProperty(false), Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), Localizable(true), Description("设置或获取合并列的集合"), Browsable(true), Category("单元格合并")] public List<string> MergeColumnNames { get { return this._mergecolumnname; } set { this._mergecolumnname = value; } } #endregion#region 构造函数
public DataGridViewEx() { SetProperty(); SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer, true); InitializeComponent(); } #endregion#region 样式设置方法
//设置样式属性 private void SetProperty() { this.AutoGenerateColumns = false; this.BackgroundColor = Color.White; //设置奇数行单元格的样式 this.AlternatingRowsDefaultCellStyle = CreatAlternatingCellStyle(); //设置默认单元格的样式 this.DefaultCellStyle = CreatDefaultCellStyle(); this.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; this.ColumnHeadersDefaultCellStyle.BackColor = Color.FromArgb(247, 247, 247); this.ColumnHeadersDefaultCellStyle.Font = new Font("宋体", 10); //this.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; this.CellBorderStyle = DataGridViewCellBorderStyle.SunkenHorizontal; this.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.None; this.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing; this.ColumnHeadersHeight = 35; this.EnableHeadersVisualStyles = false; this.RowHeadersBorderStyle = DataGridViewHeaderBorderStyle.None; this.RowHeadersVisible = false; this.SelectionMode = DataGridViewSelectionMode.FullRowSelect; this.RowTemplate.Height = 35; }//设置奇数行的样式
private DataGridViewCellStyle CreatAlternatingCellStyle() { DataGridViewCellStyle alternatingRowStyle = new DataGridViewCellStyle(); alternatingRowStyle.Font = new System.Drawing.Font("宋体", 10); //alternatingRowStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; alternatingRowStyle.BackColor = Color.White; alternatingRowStyle.ForeColor = Color.Black; alternatingRowStyle.SelectionBackColor = Color.FromArgb(255, 230, 162); alternatingRowStyle.SelectionForeColor = Color.Black; return alternatingRowStyle; }//设置默认单元格的样式
private DataGridViewCellStyle CreatDefaultCellStyle() { DataGridViewCellStyle defaultCellStyle = new DataGridViewCellStyle(); //defaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; defaultCellStyle.Font = new System.Drawing.Font("宋体", 10); defaultCellStyle.BackColor = Color.White; defaultCellStyle.ForeColor = Color.Black; defaultCellStyle.SelectionBackColor = Color.FromArgb(255, 230, 162); defaultCellStyle.SelectionForeColor = Color.Black; return defaultCellStyle; }/// <summary>
/// 设置单元格和列头有边框 /// </summary> public void SetGirdCellAndColHeaderBorderStyle() { this.CellBorderStyle = DataGridViewCellBorderStyle.Single; this.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single; } #endregion#region 重绘方法
protected override void OnPaint(PaintEventArgs pe)
{ base.OnPaint(pe); }protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
{ try { if (e.RowIndex > -1 && e.ColumnIndex > -1) { //DrawCell(e); } else { //合并表头 if (e.RowIndex == -1) { if (SpanRows.ContainsKey(e.ColumnIndex)) //被合并的列 { //画边框 Graphics g = e.Graphics; e.Paint(e.CellBounds, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);int left = e.CellBounds.Left, top = e.CellBounds.Top + 2,
right = e.CellBounds.Right, bottom = e.CellBounds.Bottom;switch (SpanRows[e.ColumnIndex].Position)
{ case 1: left += 2; break; case 2: break; case 3: right -= 2; break; }//画底色
g.FillRectangle(new SolidBrush(e.CellStyle.BackColor), left, top, right - left, (bottom - top)/2);//画中线
g.DrawLine(new Pen(this.GridColor), left-2, (top + bottom) / 2, right, (top + bottom) / 2);//写合并标题
StringFormat _sf = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };g.DrawString(e.Value + "", e.CellStyle.Font, Brushes.Black,
new Rectangle(left, (top + bottom) / 2, right - left, (bottom - top) / 2), _sf);//写原来列标题
StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Center;left = this.GetColumnDisplayRectangle(SpanRows[e.ColumnIndex].Left, true).Left - 2;
if (left < 0) left = this.GetCellDisplayRectangle(-1, -1, true).Width; right = this.GetColumnDisplayRectangle(SpanRows[e.ColumnIndex].Right, true).Right - 2; if (right < 0) right = this.Width; g.DrawString(SpanRows[e.ColumnIndex].Text, this.ColumnHeadersDefaultCellStyle.Font, new SolidBrush(e.CellStyle.ForeColor), new Rectangle(left, top, right - left, (bottom - top)/2), sf); e.Handled = true; } } } base.OnCellPainting(e); } catch { } }//绘制行号
protected override void OnRowPostPaint(DataGridViewRowPostPaintEventArgs e) { if (ShowNum) { this.RowHeadersVisible = true; SolidBrush solidBrush = new SolidBrush(Color.Black); e.Graphics.DrawString((e.RowIndex + 1).ToString(), e.InheritedRowStyle.Font, solidBrush, e.RowBounds.Location.X + 15, e.RowBounds.Location.Y + 5); } base.OnRowPostPaint(e); }//重绘滚动条
protected override void OnScroll(ScrollEventArgs e) { this.ReDrawHead(); base.OnScroll(e); }//重绘标题行
public void ReDrawHead() { foreach (int num in this.SpanRows.Keys) { base.Invalidate(base.GetCellDisplayRectangle(num, -1, true)); } }#endregion
#region 自定义方法
/// <summary> /// 画单元格 /// </summary> /// <param name="e"></param> private void DrawCell(DataGridViewCellPaintingEventArgs e) { if (e.CellStyle.Alignment == DataGridViewContentAlignment.NotSet) { e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; } Brush gridBrush = new SolidBrush(this.GridColor); SolidBrush backBrush = new SolidBrush(e.CellStyle.BackColor); SolidBrush fontBrush = new SolidBrush(e.CellStyle.ForeColor); int cellwidth; //上面相同的行数 int UpRows = 0; //下面相同的行数 int DownRows = 0; //总行数 int count = 0; if (this.MergeColumnNames.Contains(this.Columns[e.ColumnIndex].Name) && e.RowIndex != -1) { cellwidth = e.CellBounds.Width; Pen gridLinePen = new Pen(gridBrush); string curValue = e.Value == null ? "" : e.Value.ToString().Trim(); string curSelected = this.CurrentRow.Cells[e.ColumnIndex].Value == null ? "" : this.CurrentRow.Cells[e.ColumnIndex].Value.ToString().Trim(); if (!string.IsNullOrEmpty(curValue)) { #region 获取下面的行数 for (int i = e.RowIndex; i < this.Rows.Count; i++) { if (this.Rows[i].Cells[e.ColumnIndex].Value.ToString().Equals(curValue)) { //this.Rows[i].Cells[e.ColumnIndex].Selected = this.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected; if (!this.Rows[i].Cells[0].Value.ToString().Equals(this.Rows[e.RowIndex].Cells[0].Value.ToString())) break; DownRows++; if (e.RowIndex != i) { cellwidth = cellwidth < this.Rows[i].Cells[e.ColumnIndex].Size.Width ? cellwidth : this.Rows[i].Cells[e.ColumnIndex].Size.Width; } } else { break; } } #endregion #region 获取上面的行数 for (int i = e.RowIndex; i >= 0; i--) { if (this.Rows[i].Cells[e.ColumnIndex].Value.ToString().Equals(curValue)) { if (!this.Rows[e.RowIndex].Cells[0].Value.ToString().Equals(this.Rows[i].Cells[0].Value.ToString())) { break; } //this.Rows[i].Cells[e.ColumnIndex].Selected = this.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected; UpRows++; if (e.RowIndex != i) { cellwidth = cellwidth < this.Rows[i].Cells[e.ColumnIndex].Size.Width ? cellwidth : this.Rows[i].Cells[e.ColumnIndex].Size.Width; } } else { break; } } #endregion count = DownRows + UpRows - 1; if (count < 2) { return; } } if (this.Rows[e.RowIndex].Selected) { backBrush.Color = e.CellStyle.SelectionBackColor; fontBrush.Color = e.CellStyle.SelectionForeColor; } //以背景色填充 e.Graphics.FillRectangle(backBrush, e.CellBounds); //画字符串 PaintingFont(e, cellwidth, UpRows, DownRows, count); if (DownRows == 1) { e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); count = 0; } // 画右边线 e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1, e.CellBounds.Top, e.CellBounds.Right - 1, e.CellBounds.Bottom);e.Handled = true;
} } /// <summary> /// 画字符串 /// </summary> /// <param name="e"></param> /// <param name="cellwidth"></param> /// <param name="UpRows"></param> /// <param name="DownRows"></param> /// <param name="count"></param> private void PaintingFont(System.Windows.Forms.DataGridViewCellPaintingEventArgs e, int cellwidth, int UpRows, int DownRows, int count) { SolidBrush fontBrush = new SolidBrush(e.CellStyle.ForeColor); int fontheight = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Height; int fontwidth = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Width; int cellheight = e.CellBounds.Height;if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomCenter)
{ e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y + cellheight * DownRows - fontheight); } else if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomLeft) { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y + cellheight * DownRows - fontheight); } else if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomRight) { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y + cellheight * DownRows - fontheight); } else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleCenter) { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2); } else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleLeft) { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2); } else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleRight) { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2); } else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopCenter) { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1)); } else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopLeft) { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y - cellheight * (UpRows - 1)); } else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopRight) { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y - cellheight * (UpRows - 1)); } else { e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2); } } #endregion#region 合并表头方法
/// <summary>
/// 合并列 /// </summary> /// <param name="ColIndex">列的索引</param> /// <param name="ColCount">需要合并的列数</param> /// <param name="Text">合并列后的文本</param> public void AddSpanHeader(int ColIndex, int ColCount, string Text) { if (ColCount < 2) { //throw new Exception("行宽应大于等于2,合并1列无意义。"); } //将这些列加入列表 int Right = ColIndex + ColCount - 1; //同一大标题下的最后一列的索引 SpanRows[ColIndex] = new SpanInfo(Text, 1, ColIndex, Right); //添加标题下的最左列 SpanRows[Right] = new SpanInfo(Text, 3, ColIndex, Right); //添加该标题下的最右列 for (int i = ColIndex + 1; i < Right; i++) //中间的列 { SpanRows[i] = new SpanInfo(Text, 2, ColIndex, Right); } }/// <summary>
/// 清除合并表头 /// </summary> public void ClearSpanInfo() { this.SpanRows.Clear(); }#endregion
#region 获取绑定数据
/// <summary> /// 获取显示列绑定数据 /// </summary> /// <returns></returns> public DataTable GetVisibleBoundData() { DataTable dt = new DataTable(); foreach (DataGridViewColumn dgvc in this.Columns) { if (!dgvc.Visible || string.IsNullOrEmpty(dgvc.HeaderText)) { continue; } if (dgvc is DataGridViewTextBoxColumn || dgvc is DataGridViewComboBoxColumn || dgvc is DataGridViewLinkColumn) { if (!dt.Columns.Contains(dgvc.HeaderText) && dgvc.HeaderText.Length > 0) { if (dgvc.ValueType == null) { dt.Columns.Add(dgvc.HeaderText); } else { dt.Columns.Add(dgvc.HeaderText, dgvc.ValueType); } } } }foreach (DataGridViewRow dgvr in this.Rows)
{ if (dgvr.IsNewRow) { continue; } if (string.IsNullOrEmpty(dgvr.Cells[1].Value != null ? dgvr.Cells[1].Value.ToString() : "")) { continue; } DataRow dr = dt.NewRow(); foreach (DataGridViewColumn dgvc in this.Columns) { if (dt.Columns.Contains(dgvc.HeaderText)) { if (dgvr.Cells[dgvc.Name].FormattedValue.ToString().Length > 0) { dr[dgvc.HeaderText] = dgvr.Cells[dgvc.Name].FormattedValue; } } } dt.Rows.Add(dr); }return dt;
} #endregion } [StructLayout(LayoutKind.Sequential)] public struct SpanInfo { /// <summary> /// 合并后的标题 /// </summary> public string Text; /// <summary> /// 本身位置(是左边界列还是有边界列) /// </summary> public int Position; /// <summary> /// 左边界列 /// </summary> public int Left; /// <summary> /// 右边界列 /// </summary> public int Right; public SpanInfo(string Text, int Position, int Left, int Right) { this.Text = Text; this.Position = Position; this.Left = Left; this.Right = Right; } }}
使用:
DataTable dt =
new
DataTable();
dt.Columns.Add(
"1"
);
dt.Columns.Add(
"2"
);
dt.Columns.Add(
"3"
);
dt.Columns.Add(
"4"
);
dt.Rows.Add(
"中国"
,
"上海"
,
"5000"
,
"7000"
);
dt.Rows.Add(
"中国"
,
"北京"
,
"3000"
,
"5600"
);
dt.Rows.Add(
"美国"
,
"纽约"
,
"6000"
,
"8600"
);
dt.Rows.Add(
"美国"
,
"华劢顿"
,
"8000"
,
"9000"
);
dt.Rows.Add(
"英国"
,
"伦敦"
,
"7000"
,
"8800"
);
this
.rowMergeView1.DataSource = dt;
this
.rowMergeView1.ColumnHeadersHeight = 40;
this
.rowMergeView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
//
this
.rowMergeView1.MergeColumnNames.Add(
"Column1"
);
this
.rowMergeView1.AddSpanHeader(2, 2,
"XXXX"
);