前几天Jo Muncher's Blog上看到《VS2005的DataGridView 多维合并标题 功能拓展》的文章,对我制作DataGridView多表头大有帮助,并把代码进行了调试,发现还有问题。近日把VB代码修改成C#代码,并对部分BUG进行修改,最终还是把问题攻克了,效果比较理想。见下图
源代码如下:
HeaderUnitView.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Sql;
using System.Text;
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace DataGridViewSampCs
...{
public partial class HeaderUnitView : DataGridView
...{
private TreeView[] _columnTreeView;
private ArrayList _columnList = new ArrayList();
private int _cellHeight = 17;
private int _columnDeep = 1;
/**//// <summary>
/// 构造函数
/// </summary>
public HeaderUnitView()
...{
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]; }
}
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;
}
}
/**////<summary>
///绘制合并表头
///</summary>
///<param name="node">合并表头节点</param>
///<param name="e">绘图参数集</param>
///<param name="level">结点深度</param>
///<remarks></remarks>
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
// , Brushes.Black
// , uhRectangle
// , textFormat);
e.Graphics.DrawString(node.Text, this.Font
, Brushes.Black
, 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 -<
using System.Collections;
using System.Collections.Generic;
using System.Data.Sql;
using System.Text;
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace DataGridViewSampCs
...{
public partial class HeaderUnitView : DataGridView
...{
private TreeView[] _columnTreeView;
private ArrayList _columnList = new ArrayList();
private int _cellHeight = 17;
private int _columnDeep = 1;
/**//// <summary>
/// 构造函数
/// </summary>
public HeaderUnitView()
...{
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]; }
}
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;
}
}
/**////<summary>
///绘制合并表头
///</summary>
///<param name="node">合并表头节点</param>
///<param name="e">绘图参数集</param>
///<param name="level">结点深度</param>
///<remarks></remarks>
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
// , Brushes.Black
// , uhRectangle
// , textFormat);
e.Graphics.DrawString(node.Text, this.Font
, Brushes.Black
, 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 -<