DataGridView 多层列头、合并单元格
来源:互联网 发布:佳能打印机排版软件 编辑:程序博客网 时间:2024/05/22 10:26
DataGridView扩展功能 多行列头、合并单元格
http://blog.sina.com.cn/s/blog_63160fa801014ity.html
public partial class ExtDataGridView : DataGridView { #region 变量、属性 /// <summary> /// 列头信息树 /// </summary> private TreeView _columnTreeView = null; /// <summary> /// DataGirdView列 /// </summary> private ArrayList _columnList = new ArrayList(); /// <summary> /// 单元格高度 /// </summary> private int _cellHeight = 17; /// <summary> /// 获取或设置单元格高度 /// </summary> public int CellHeight { get { return _cellHeight; } set { _cellHeight = value; } } private List<string> _mergecolumnname = new List<string>(); /// <summary> /// 列头层数 /// </summary> private int _columnDeep = 1; /// <summary> /// 滚动时刷新 /// </summary> private bool _hscrollRefresh = false; /// <summary> /// 水平滚动时是否刷新表头,数据较多时可能会闪烁,不刷新时可能显示错误 /// </summary> [Description("水平滚动时是否刷新表头,数据较多时可能会闪烁,不刷新时可能显示错误")] public bool RefreshAtHscroll { get { return _hscrollRefresh; } set { _hscrollRefresh = value; } } [Description("设置或获得合并表头树的深度")] public int ColumnDeep { get { if (this.Columns.Count == 0) _columnDeep = 1; this.ColumnHeadersHeight = _cellHeight * _columnDeep; return _columnDeep; } set { if (value < 1) _columnDeep = 1; else _columnDeep = value; this.ColumnHeadersHeight = _cellHeight * _columnDeep; } } [Description("添加合并式单元格绘制的所需要的节点对象")] public TreeView ColumnTreeView { get { return _columnTreeView; } set { _columnTreeView = value; } } [Description("设置添加的字段树的相关属性")] public TreeView ColumnTreeViewNode { get { if (_columnTreeView == null) return null; return _columnTreeView; } } /// <summary> /// 设置或获取合并列的集合 /// </summary> [MergableProperty(false)] [Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] [DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Visible)] [Localizable(true)] [Description("设置或获取合并列的集合"), Browsable(true), Category("单元格合并")] public List<string> MergeColumnNames { get { return _mergecolumnname; } set { _mergecolumnname = value; } } /// <summary> /// 获取列头数中的实际列头 /// </summary> public ArrayList NadirColumnList { get { if (_columnTreeView == null) return null; //if (_columnTreeView[0] == null) // return null; if (_columnTreeView.Nodes == null) return null; if (_columnTreeView.Nodes.Count == 0) return null; _columnList.Clear(); GetNadirColumnNodes(_columnList, _columnTreeView.Nodes[0], false); return _columnList; } } #endregion #region 构造函数 /// <summary> /// 创建DataGridView默认实例 /// </summary> public ExtDataGridView() { InitializeComponent(); this.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing; //设置列高度显示模式 //表头居中对齐 base.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; //将列填充整个DataGrid //base.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; } #endregion #region 列头 ///<summary> ///绘制合并表头 ///</summary> ///<param name="node">合并表头节点</param> ///<param name="e">绘图参数集</param> ///<param name="level">结点深度</param> ///<remarks></remarks> public void PaintUnitHeader(TreeNode node, DataGridViewCellPaintingEventArgs e, int level) { //根节点时退出递归调用 if (level == 0) return; RectangleF uhRectangle; int uhWidth; SolidBrush gridBrush = new SolidBrush(this.GridColor); SolidBrush backColorBrush = new SolidBrush(e.CellStyle.BackColor); Pen gridLinePen = new Pen(gridBrush); StringFormat textFormat = new StringFormat(); textFormat.Alignment = StringAlignment.Center; uhWidth = GetUnitHeaderWidth(node); if (node.Nodes.Count == 0) { uhRectangle = new Rectangle(e.CellBounds.Left, e.CellBounds.Top + node.Level * _cellHeight, uhWidth - 1, _cellHeight * (_columnDeep - node.Level) - 1); } else { uhRectangle = new Rectangle( e.CellBounds.Left, e.CellBounds.Top + node.Level * _cellHeight, uhWidth - 1, _cellHeight - 1); } //画矩形 e.Graphics.FillRectangle(backColorBrush, uhRectangle); //划底线 e.Graphics.DrawLine(gridLinePen , uhRectangle.Left , uhRectangle.Bottom , uhRectangle.Right , uhRectangle.Bottom); //划右端线 e.Graphics.DrawLine(gridLinePen , uhRectangle.Right , uhRectangle.Top , uhRectangle.Right , uhRectangle.Bottom); ////写字段文本 e.Graphics.DrawString(node.Text, this.Font , new SolidBrush(e.CellStyle.ForeColor) , uhRectangle.Left + uhRectangle.Width / 2 - e.Graphics.MeasureString(node.Text, this.Font).Width / 2 - 1 , uhRectangle.Top + uhRectangle.Height / 2 - e.Graphics.MeasureString(node.Text, this.Font).Height / 2); //递归调用() if (node.PrevNode == null) if (node.Parent != null) PaintUnitHeader(node.Parent, e, level - 1); } /// <summary> /// 获得合并标题字段的宽度 /// </summary> /// <param name="node">字段节点</param> /// <returns>字段宽度</returns> /// <remarks></remarks> private int GetUnitHeaderWidth(TreeNode node) { //获得非最底层字段的宽度 int uhWidth = 0; int index = 0; //获得最底层字段的宽度 if (node.Nodes == null || node.Nodes.Count == 0) { index = GetColumnListNodeIndex(node); if (this.Columns.Count > index) return this.Columns[index].Width; else return uhWidth; } //if (node.Nodes.Count == 0) // return this.Columns[GetColumnListNodeIndex(node)].Width; for (int i = 0; i <= node.Nodes.Count - 1; i++) { uhWidth = uhWidth + GetUnitHeaderWidth(node.Nodes[i]); } return uhWidth; } /// <summary> /// 获得底层字段索引 /// </summary> ///' <param name="node">底层字段节点</param> /// <returns>索引</returns> /// <remarks></remarks> private int GetColumnListNodeIndex(TreeNode node) { for (int i = 0; i <= _columnList.Count - 1; i++) { if (((TreeNode)_columnList[i]).Equals(node)) return i; } return -1; } /// <summary> /// 获得底层字段集合 /// </summary> /// <param name="alList">底层字段集合</param> /// <param name="node">字段节点</param> /// <param name="checked">向上搜索与否</param> /// <remarks></remarks> private void GetNadirColumnNodes(ArrayList alList, TreeNode node, Boolean isChecked) { if (isChecked == false) { if (node.FirstNode == null) { alList.Add(node); if (node.NextNode != null) { GetNadirColumnNodes(alList, node.NextNode, false); return; } if (node.Parent != null) { GetNadirColumnNodes(alList, node.Parent, true); return; } } else { if (node.FirstNode != null) { GetNadirColumnNodes(alList, node.FirstNode, false); return; } } } else { if (node.FirstNode == null) return; else { if (node.NextNode != null) { GetNadirColumnNodes(alList, node.NextNode, false); return; } if (node.Parent != null) { GetNadirColumnNodes(alList, node.Parent, true); return; } } } } #endregion #region 重写方法 /// <summary> /// 单元格绘制(重写) /// </summary> /// <param name="e"></param> /// <remarks></remarks> protected override void OnCellPainting(System.Windows.Forms.DataGridViewCellPaintingEventArgs e) { try { if (e.RowIndex > -1 && e.ColumnIndex > -1 && MergeColumnNames.Count > 0) { MergeCell(e); } else if (_columnTreeView != null && _columnTreeView.Nodes.Count > 0) { //行标题不重写 if (e.ColumnIndex < 0) { base.OnCellPainting(e); return; } if (_columnDeep == 1) { base.OnCellPainting(e); return; } //绘制表头 if (e.RowIndex == -1 && NadirColumnList != null) { if (e.ColumnIndex >= NadirColumnList.Count) { e.Handled = true; return; } PaintUnitHeader((TreeNode)NadirColumnList[e.ColumnIndex] , e , _columnDeep); e.Handled = true; } } } catch (Exception ex) { Console.WriteLine(ex.Message); } } /// <summary> /// 滚动时刷新 /// </summary> /// <param name="e"></param> protected override void OnScroll(ScrollEventArgs e) { bool scrollDirection = (e.ScrollOrientation == ScrollOrientation.HorizontalScroll); base.OnScroll(e); if (RefreshAtHscroll && scrollDirection) this.Refresh(); } /// <summary> /// 列宽度改变的重写 /// </summary> /// <param name="e"></param> protected override void OnColumnWidthChanged(DataGridViewColumnEventArgs e) { //Graphics g = Graphics.FromHwnd(this.Handle); //float uwh = g.MeasureString(e.Column.HeaderText, this.Font).Width; //if (uwh >= e.Column.Width) { e.Column.Width = Convert.ToInt16(uwh); } if (MergeColumnNames.Count > 0 || (_columnTreeView != null && _columnTreeView.Nodes.Count > 0)) { this.Refresh(); } base.OnColumnWidthChanged(e); } /// <summary> /// 值变更时刷新 /// </summary> /// <param name="e"></param> protected override void OnCellValueChanged(DataGridViewCellEventArgs e) { string colName = this.Columns[e.ColumnIndex].Name; if (this.MergeColumnNames.Contains(colName)) this.Refresh(); base.OnCellValueChanged(e); } #endregion #region 合并单元格 /// <summary> /// 画单元格 /// </summary> /// <param name="e"></param> private void MergeCell(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 != null && 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; 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 != null && 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; 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); if (e.RowIndex == this.Rows.Count - 1) e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1); 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 == null ? string.Empty : e.Value.ToString(), e.CellStyle.Font).Height; int fontwidth = (int)e.Graphics.MeasureString(e.Value == null ? string.Empty : 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 private void InitializeComponent() { ((System.ComponentModel.ISupportInitialize)(this)).BeginInit(); this.SuspendLayout(); // // HeaderUnitView // this.RowTemplate.Height = 23; ((System.ComponentModel.ISupportInitialize)(this)).EndInit(); this.ResumeLayout(false); } }
- DataGridView 多层列头、合并单元格
- 多层头,多列头,合并列头,双列头
- DataGridView合并单元格 编辑单元格
- DataGridView 合并同一列中值相同的相邻单元格 合并单元格
- datagridview 合并单元格
- DataGridView 合并单元格
- datagridview单元格合并
- DataGridView合并单元格
- 合并datagridview单元格
- DataGridView合并单元格
- DataGridView 合并单元格
- *合并DataGridView单元格*
- 【转】DataGridView单元格合并
- Datagridview合并单元格
- datagridview合并单元格,行合并
- DataGridView列头checkbox
- DataGridView合并列标题
- DataGridView 列合并
- Fatal error: Call-time pass-by-reference has been removed in D:\xampp\php\includes\duibifun.php on l
- linux 用户环境变量介绍
- vim 查看函数列表
- TCP端口状态说明ESTABLISHED、TIME_WAIT
- java动态代理 JDK、Cglib动态代理
- DataGridView 多层列头、合并单元格
- 管理时间
- addr2line命令
- Wix note (3)
- 程序员技术练级攻略
- js,css,smarty相对路径
- ubuntu上samba服务器搭建
- 一些API
- 三层交换机间的静态路由配置应用实训