对于.NET 原本提供的DataGridView控件,制作成如下形式的表格是毫无压力的。
但是如果把表格改了一下,变成如下形式
传统的DataGridView就做不到了,如果扩展一下还是行的,有不少网友也扩展了DataGridView控件,不过有些也只能制作出二维的表头。或者使用第三方的控件,之前也用过DevExpress的BoundGridView。不过在没有可使用的第三方控件的情况下,做到下面的效果,就有点麻烦了。
那得自己扩展了,不过最后还是用了一个控件库的报表控件,Telerik的Reporting。不过我自己还是扩展了DataGridView,使之能制作出上面的报表。
准备
学习了一些网友的代码,原来制作这个多维表头都是利用GDI+对DataGirdView的表头进行重绘。
用到的方法包括
Graphics.FillRectangle //填充一个矩形
Graphics.DrawLine //画一条线
Graphics.DrawString //写字符串
此外为了方便组织表头,本人还定义了一个表头的数据结构 HeaderItem 和 HeaderCollection 分别作为每个表头单元格的数据实体和整个表头的集合。
HeaderItem的定义如下
复制代码 代码如下:
public class HeaderItem
{
private int _startX;//起始横坐标
private int _startY;//起始纵坐标
private int _endX; //终止横坐标
private int _endY; //终止纵坐标
private bool _baseHeader; //是否基础表头
public HeaderItem(int startX, int endX, int startY, int endY, string content)
{
this._endX = endX;
this._endY = endY;
this._startX = startX;
this._startY = startY;
this.Content = content;
}
public HeaderItem(int x, int y, string content):this(x,x,y,y,content)
{
}
public HeaderItem()
{
}
public static HeaderItem CreateBaseHeader(int x,int y,string content)
{
HeaderItem header = new HeaderItem();
header._endX= header._startX = x;
header._endY= header._startY = y;
header._baseHeader = true;
header.Content = content;
return header;
}
public int StartX
{
get { return _startX; }
set
{
if (value > _endX)
{
_startX = _endX;
return;
}
if (value < 0) _startX = 0;
else _startX = value;
}
}
public int StartY
{
get { return _startY; }
set
{
if (_baseHeader)
{
_startY = 0;
return;
}
if (value > _endY)
{
_startY = _endY;
return;
}
if (value < 0) _startY = 0;
else _startY = value;
}
}
public int EndX
{
get { return _endX; }
set
{
if (_baseHeader)
{
_endX = _startX;
return;
}
if (value < _startX)
{
_endX = _startX;
return;
}
_endX = value;
}
}
public int EndY
{
get { return _endY; }
set
{
if (value < _startY)
{
_endY = _startY;
return;
}
_endY = value;
}
}
public bool IsBaseHeader
{get{ return _baseHeader;} }
public string Content { get; set; }
}