实现DataGridView的多层表头
来源:互联网 发布:utorrent for linux 编辑:程序博客网 时间:2024/05/01 16:04
因工作需要使用DataGridView实现多层表头的显示,在网上找了些实现的例子(在此感谢manimanihome的博文提供原始素材,需要看原理的请转过去查看),但在绘制时的计算逻辑上有些问题,自己经过了一些修改勉强可以满足需要了。
还存在的问题有:在拖动改变列宽后有时候字/线没有刷过来;鼠标在标题栏上移动时会不停的刷影响效果。
使用时需要注意3个地方:主要类包含MultiHead,MutiHeadDGV:DataGridView;
Datagridview的ColumnHeadersHeightSizeMode属性最好设为EnableResizing;
布局的列数需要与多层列的最低级标题数一致。
下面上代码:
MultiHead类
class MultiHead { #region ...静态... private static SortedList<string, int> cellPointX; /// <summary> /// 获取标题单元格的左边距 /// </summary> /// <param name="rowindex"></param> /// <param name="columnindex"></param> /// <returns></returns> private static int GetCellPointX(int rowindex, int columnindex) { string key = string.Format("{0}.{1}",rowindex,columnindex); return cellPointX[key]; } /// <summary> /// 设置或更新标题单元格的左边距 /// </summary> /// <param name="rowindex"></param> /// <param name="columnindex"></param> /// <param name="x"></param> /// <returns></returns> private static void SetCellPoint(int rowindex, int columnindex, int x) { if (cellPointX == null) cellPointX = new SortedList<string, int>(); string key = string.Format("{0}.{1}", rowindex, columnindex); if (cellPointX.ContainsKey(key)) cellPointX[key] = x; else cellPointX.Add(key, x); } #endregion private DataGridView dataGridView; public MultiHead(DataGridView grid) { this.dataGridView = grid; string title = ""; for (int i = 0; i != this.dataGridView.Columns.Count - 1; ++i) { title += this.dataGridView.Columns[i].HeaderText + ","; } title = title.Substring(1, title.Length - 2); this.titleHead = new string[] { title }; } //通過构造函數來限制title的格式,始終与grid保持一致 public MultiHead(DataGridView grid, string[] title) { //grid不等于null for (int i = 0; i != title.Length - 1; ++i) { string[] s = title[i].Split(','); if (grid.Columns.Count == s.Length) { continue; } else { throw new Exception("title的元素個數与grid的欄位總數不一致."); } } this.dataGridView = grid; this.titleHead = title; } private string[] titleHead; public string[] TitleHead { get { return titleHead; } } public string Draw(DataGridViewCellPaintingEventArgs e) { string message = string.Empty; if (e.RowIndex == -1) { using ( Brush gridBrush = new SolidBrush(this.dataGridView.GridColor), backColorBrush = new SolidBrush(e.CellStyle.BackColor)) { using (Pen gridLinePen = new Pen(gridBrush)) { gridLinePen.Color = dataGridView.GridColor; if (e.ColumnIndex == -1) { e.Graphics.FillRectangle(backColorBrush, e.CellBounds); //畫右邊線 e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1, e.CellBounds.Top, e.CellBounds.Right - 1, e.CellBounds.Bottom); //畫bottom線 e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1, e.CellBounds.Right, e.CellBounds.Bottom - 1); } else { //第一行已经绘制的上一个标题 string[] drawtitles = new string[titleHead.Length]; for (int i = 0; i < titleHead.Length; ++i)//逐行畫 { SetCellPoint(i, e.ColumnIndex,e.CellBounds.Width); int width; int height; int locationX; int locationY; int paintingwidth=0; string[] currRow = titleHead[i].Split(','); width = e.CellBounds.Width; //開始列 int startColIndex = e.ColumnIndex; while (startColIndex > 0) { if (currRow[e.ColumnIndex] == currRow[startColIndex - 1]) { if (this.dataGridView.Columns[startColIndex - 1].Visible) { width += this.dataGridView.Columns[startColIndex - 1].Width; } if (startColIndex <= e.ColumnIndex) paintingwidth += this.dataGridView.Columns[startColIndex].Width; startColIndex--; } else { break; } } paintingwidth += GetCellPointX(i, startColIndex); //結束列 int endColIndex = e.ColumnIndex; while (endColIndex < this.dataGridView.Columns.Count - 1) { if (currRow[e.ColumnIndex] == currRow[endColIndex + 1]) { if (this.dataGridView.Columns[endColIndex + 1].Visible) { width += this.dataGridView.Columns[endColIndex + 1].Width; } endColIndex++; } else { break; } } height = e.CellBounds.Height / titleHead.Length; //開始行 int startRowIndex = i; while (startRowIndex > 0) { string[] overRow = titleHead[startRowIndex - 1].Split(','); if (currRow[e.ColumnIndex] == overRow[e.ColumnIndex]) { int overStartColIndex = e.ColumnIndex; int overEndColIndex = e.ColumnIndex; while (overStartColIndex > 0) { if (overRow[e.ColumnIndex] == currRow[overStartColIndex - 1]) { overStartColIndex--; } else { break; } } while (overEndColIndex < this.dataGridView.Columns.Count - 1) { if (overRow[e.ColumnIndex] == overRow[overEndColIndex + 1]) { overEndColIndex++; } else { break; } } if (startColIndex == overStartColIndex && endColIndex == overEndColIndex) { height += e.CellBounds.Height / titleHead.Length; startRowIndex--; } else { break; } } else { break; } } //結束行 int endRowIndex = i; while (endRowIndex < titleHead.Length - 1) { string[] lowRow = titleHead[endRowIndex + 1].Split(','); if (currRow[e.ColumnIndex] == lowRow[e.ColumnIndex]) { int lowStartColIndex = e.ColumnIndex; int lowEndColIndex = e.ColumnIndex; while (lowStartColIndex > 0) { if (lowRow[e.ColumnIndex] == currRow[lowStartColIndex - 1]) { lowStartColIndex--; } else { break; } } while (lowEndColIndex < this.dataGridView.Columns.Count - 1) { if (lowRow[e.ColumnIndex] == lowRow[lowEndColIndex + 1]) { lowEndColIndex++; } else { break; } } if (startColIndex == lowStartColIndex && endColIndex == lowEndColIndex) { height += e.CellBounds.Height / titleHead.Length; endRowIndex++; } else { break; } } else { break; } } locationX = e.CellBounds.Right - paintingwidth;// e.CellBounds.Right - width; locationY = e.CellBounds.Bottom - (titleHead.Length - endRowIndex - 1) * e.CellBounds.Height / titleHead.Length - height; Rectangle recCell = new Rectangle(locationX, locationY, width, height); message += string.Format("{0}:({1},{2},{3},{4})\r\n", currRow[e.ColumnIndex], locationX, locationY, width, height); //erase cell e.Graphics.FillRectangle(backColorBrush, recCell); //畫right和bottom線 e.Graphics.DrawLine(gridLinePen, locationX + width - 1, locationY - 1, locationX + width - 1, locationY + height - 1); e.Graphics.DrawLine(gridLinePen, locationX - 1, locationY + height - 1, locationX + width - 1, locationY + height - 1); //畫文字 StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Center; e.Graphics.DrawString(currRow[e.ColumnIndex], e.CellStyle.Font, Brushes.Black, recCell, sf); } } e.Handled = true; } } } return message; } }
MutiHeadDGV:DataGridView
class MutiHeadDGV:DataGridView { private string[] titleHead; public string[] TitleHead { get { return this.titleHead; } set { this.titleHead = value; } } protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e) { titleHead = new string[] { "基础资料,基础资料,基础资料,基础资料,附加信息,附加信息,附加信息,附加信息,描述", "姓名,籍贯,出生时间,性别,现住址,职业,收入,爱好,描述"}; MultiHead m = new MultiHead(this, titleHead); } }
TitleHead属性<strong style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">多层标题是可以在外部赋值的哦</strong>
0 0
- 实现DataGridView的多层表头
- DataGridView任意多层表头
- .datagrid多层表头功能的实现
- DataGridView合并表头实现 、二维表头的实现
- DataGridView合并表头实现 、二维表头的实现、单元格合并
- DataGridView合并表头实现 、二维表头的实现
- 实现DataGridView的双层表头功能
- 实现DataGridView的双层表头功能
- 实现多行表头的DATAGRIDVIEW
- C#WINFORM 的DATAGRIDVIEW多表头实现
- Datagridview 实现二维表头
- Datagridview 实现二维表头
- DataGridView实现多维表头
- Datagridview 实现二维表头
- DataGridView实现多维表头
- 多维表头的DataGridView
- [转]Datagridview 实现二维表头
- [WinForm]Datagridview 实现二维表头
- Window下UDP(socket)接和收数据案例
- QT 版本历史
- (CF) D. A Lot of Games
- Hadoop2.2源代码编译
- ubantu /usr/include/features.h:324:26: 致命错误: bits/predefs.h:没有那个文件或目录编译中断 错误解决
- 实现DataGridView的多层表头
- hdu 2594 Simpsons’ Hidden Talents KMP
- iOS中防止多个按钮同时点击出现的问题
- 如何理解“可靠性”和“可用性”?
- 【最短路算法模板】
- kmemleak 内存泄露检测
- ViewPager循环效果
- 编程之美 4.2 瓷砖覆盖地板 扩展问题
- xcode 调试的时候不显示 c 变量值