热门搜索 :
考研考公
您的当前位置:首页正文

DataGridView二维表头与合并单元格

来源:伴沃教育


DataGridView二维表头与合并单元格

1、在项目中添加“组件类”。

2、所引用的命名空间如下:

using System;

using System.Collections.Generic; using System.Linq; using System.Text;

using System.Collections;

using System.ComponentModel; using System.Windows.Forms; using System.Drawing;

using System.Drawing.Design; using System.Diagnostics;

3、DataGridView二维表头与合并单元格类,继承DataGridView类

public partial class HeaderUnitView : DataGridView {

private TreeView[] _columnTreeView;

private ArrayList _columnList = new ArrayList();

private int _cellHeight = 17; public int CellHeight {

get { return _cellHeight; } set { _cellHeight = value; } }

private int _columnDeep = 1;

private bool HscrollRefresh = false; ///

/// 水平滚动时是否刷新表头,数据较多时可能会闪烁,不刷新时可能显示错误 ///

[Description(\"水平滚动时是否刷新表头,数据较多时可能会闪烁,不刷新时可能显示错误\")]

public bool RefreshAtHscroll {

get { return HscrollRefresh; } set { HscrollRefresh = value; } }

///

/// 构造函数 ///

public HeaderUnitView() {

InitializeComponent(); this.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing; //设置列高度显示模式 }

public HeaderUnitView(IContainer container) {

container.Add(this); InitializeComponent(); }

[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 {

if (_columnTreeView != null) {

for (int i = 0; i <= _columnTreeView.Length - 1; i++) _columnTreeView[i].Dispose(); }

_columnTreeView = value; } }

[Description(\"设置添加的字段树的相关属性\")] public TreeView ColumnTreeViewNode {

get { return _columnTreeView[0]; } }

///

/// 设置或获取合并列的集合 ///

[MergableProperty(false)]

[Editor(\"System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\ [DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Visible)]

[Localizable(true)]

[Description(\"设置或获取合并列的集合\"), Browsable(true), Category(\"单元格合并\")] public List MergeColumnNames { get {

return _mergecolumnname; }

set {

_mergecolumnname = value; } }

private List _mergecolumnname = new List(); public ArrayList NadirColumnList { get {

if (_columnTreeView == null) return null;

if (_columnTreeView[0] == null) return null;

if (_columnTreeView[0].Nodes == null) return null;

if (_columnTreeView[0].Nodes.Count == 0) return null;

_columnList.Clear();

GetNadirColumnNodes(_columnList, _columnTreeView[0].Nodes[0], false); return _columnList; } }

///

///绘制合并表头 ///

///合并表头节点 ///绘图参数集 ///结点深度 /// public void PaintUnitHeader( TreeNode node,

System.Windows.Forms.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);

}

///

/// 获得合并标题字段的宽度 ///

/// 字段节点 /// 字段宽度 ///

private int GetUnitHeaderWidth(TreeNode node) {

//获得非最底层字段的宽度 int uhWidth = 0;

//获得最底层字段的宽度 if (node.Nodes == null)

return this.Columns[GetColumnListNodeIndex(node)].Width; 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; }

///

/// 获得底层字段索引 ///

///' 底层字段节点 /// 索引 ///

private int GetColumnListNodeIndex(TreeNode node) {

for (int i = 0; i <= _columnList.Count - 1; i++) {

if (((TreeNode)_columnList[i]).Equals(node)) return i; }

return -1; }

///

/// 获得底层字段集合 ///

/// 底层字段集合 /// 字段节点

/// 向上搜索与否

///

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; } } } }

///

/// 滚动

///

///

protected override void OnScroll(ScrollEventArgs e) {

bool scrollDirection = (e.ScrollOrientation == ScrollOrientation.HorizontalScroll); base.OnScroll(e);

if (RefreshAtHscroll && scrollDirection) this.Refresh(); }

///

/// 列宽度改变的重写 ///

///

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); } base.OnColumnWidthChanged(e); }

///

/// 单元格绘制(重写) ///

/// /// protected override

OnCellPainting(System.Windows.Forms.DataGridViewCellPaintingEventArgs e) { try {

if (e.RowIndex > -1 && e.ColumnIndex > -1) {

DrawCell(e); }

void

else {

//行标题不重写 if (e.ColumnIndex < 0) {

base.OnCellPainting(e); return; }

if (_columnDeep == 1) {

base.OnCellPainting(e); return; }

//绘制表头

if (e.RowIndex == -1) {

if (e.ColumnIndex >= NadirColumnList.Count) { e.Handled = true; return; } PaintUnitHeader((TreeNode)NadirColumnList[e.ColumnIndex] , e

, _columnDeep); e.Handled = true; } } } catch { } }

#region 合并单元格 ///

/// 画单元格 ///

///

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; 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)) { //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; } }

///

/// 画字符串 ///

///

/// /// ///

///

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 }

4、HeaderUnitView控件的具体使用方法

示例界面:重新生成解决方案后,直接在工具栏拖放控件(下面是两种方法)

一、通过属性设置

(1)设置ColumnHeadersHeightSizeMode属性为:DisableResizing (2)编辑列

(3)设置ColumnDeep属性为:2;设置CellHeight和ColumnHeadersHeight属性 (4)设置ColumnTreeView属性,添加TreeView

(5)设置ColumnTreeViewNode属性,为TreeView添加节点。(在ColumnTreeView中属性

中的Node里添加节点如下)

(6)设置RefreshAtHscroll属性为True。 (7)利用DataGridView方法绑定数据即可。

二、通过代码设置

//添加列

DataGridViewTextBoxColumn tcDM = new DataGridViewTextBoxColumn();

tcDM.HeaderText = \"班级代码\"; tcDM.Name = \"DM\";

//tcDM.DataPropertyName = \"DM\"; tcDM.ReadOnly = true;

//tcDM.SortMode = DataGridViewColumnSortMode.NotSortable;

//tcDM.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; dgv.Columns.Add(tcDM);

DataGridViewTextBoxColumn tcMC = new DataGridViewTextBoxColumn(); tcMC.HeaderText = \"班级名称\"; tcMC.Name = \"MC\"; tcMC.ReadOnly = true; dgv.Columns.Add(tcMC);

DataGridViewTextBoxColumn tcNan = new DataGridViewTextBoxColumn(); tcNan.HeaderText = \"男\"; tcNan.Name = \"Nan\"; tcNan.ReadOnly = true; dgv.Columns.Add(tcNan);

DataGridViewTextBoxColumn tcNv = new DataGridViewTextBoxColumn(); tcNv.HeaderText = \"女\"; tcNv.Name = \"Nv\"; tcNv.ReadOnly = true; dgv.Columns.Add(tcNv); //增加TreeView

TreeView tv = new TreeView();

TreeNode tnDM = new TreeNode(\"班级代码\"); tv.Nodes.Add(tnDM);

TreeNode tnMC = new TreeNode(\"班级名称\"); tv.Nodes.Add(tnMC);

TreeNode tnSex = new TreeNode(\"性别\"); tv.Nodes.Add(tnSex);

TreeNode tnNan = new TreeNode(\"男\"); tnSex.Nodes.Add(tnNan);

TreeNode tnNv = new TreeNode(\"女\"); tnSex.Nodes.Add(tnNv);

dgv.ColumnTreeView = new TreeView[] { tv }; //设置其他属性

dgv.AutoGenerateColumns = false; //不自动增加列 dgv.RowHeadersVisible = false; //行头不可见 dgv.AllowUserToAddRows = false;

dgv.RowTemplate.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; dgv.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing; dgv.ColumnDeep = 2;

dgv.CellHeight = 25;

dgv.ColumnHeadersHeight = 50; dgv.RefreshAtHscroll = true;

三、添加一条数据

dgv.Rows.Add(); //添加行

dgv.Rows[0].Cells[\"DM\"].Value = \"2003001\"; dgv.Rows[0].Cells[\"MC\"].Value = \"网络一班\"; ; dgv.Rows[0].Cells[\"Nan\"].Value = \"26人\"; dgv.Rows[0].Cells[\"Nv\"].Value = \"18人\";

四、合并单元格

headerUnitView1.MergeColumnNames.Add(\"Column11\");//Column11需要合并单元格的列 -------------------------------------------------------------------------------------------------- 如果有三层表头就把ColumnDeep改成3,,依次...

因篇幅问题不能全部显示,请点此查看更多更全内容

Top