现在在网上基本上有两种方法实现winform多表头。一种是将winform表头重画,代码如下:
private void DataGridViewEx_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)

{
if (e.RowIndex == -1)

{
// int w = dataGridView1.HorizontalScrollingOffset + dataGridView1.TopLeftHeaderCell.Size.Width + dataGridView1.Columns[0].Width + 10;


Rectangle newRect = new Rectangle(e.CellBounds.X + 1,
e.CellBounds.Y + 1, e.CellBounds.Width - 4,
e.CellBounds.Height - 4);

using (
Brush gridBrush = new SolidBrush(this.GridColor),
backColorBrush = new SolidBrush(e.CellStyle.BackColor))

{
using (Pen gridLinePen = new Pen(gridBrush))

{
// Erase the cell.
e.Graphics.FillRectangle(backColorBrush, e.CellBounds);

// Draw the grid lines (only the right and bottom lines;
// DataGridView takes care of the others).
e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left,
e.CellBounds.Bottom - 1, e.CellBounds.Right - 1,
e.CellBounds.Bottom - 1);
if (e.ColumnIndex > -1 && topRow!=null&&topRow.Cells[e.ColumnIndex].ColSpan>1)

{
e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1,
e.CellBounds.Top + e.ClipBounds.Height / 2, e.CellBounds.Right - 1,
e.CellBounds.Bottom);
}
else

{
e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1,
e.CellBounds.Top, e.CellBounds.Right - 1,
e.CellBounds.Bottom);
}

// Draw the inset highlight box.
// e.Graphics.DrawRectangle(Pens.Blue, newRect);

int scale = e.CellBounds.Height/3;
if (e.ColumnIndex > -1 && topRow.Cells[e.ColumnIndex].Text != null)

{
scale= e.CellBounds.Height / 2;
e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - e.CellBounds.Height / 2, e.CellBounds.Right, e.CellBounds.Bottom - e.CellBounds.Height / 2);
}
// Draw the text content of the cell, ignoring alignment.


if (e.Value != null)

{
e.Graphics.DrawString(e.Value.ToString(), e.CellStyle.Font,
Brushes.Crimson, e.CellBounds.X + 2,
e.CellBounds.Y + scale+ 2, StringFormat.GenericDefault);



}




if (e.ColumnIndex > -1 && topRow.Cells[e.ColumnIndex].RelateIndex > -1 && topRow.Cells[e.ColumnIndex].Text!=null)

{
Rectangle recCell = new Rectangle(e.CellBounds.X - 1 - topRow.Cells[e.ColumnIndex].SpanRowWith,
e.CellBounds.Y + 1, topRow.Cells[e.ColumnIndex].SpanRowWith,
e.CellBounds.Height / 2);


StringFormat sf = new StringFormat();

sf.Alignment = StringAlignment.Center;


e.Graphics.DrawString(topRow.Cells[e.ColumnIndex].Text, e.CellStyle.Font, Brushes.Crimson, recCell, sf);

}
e.Handled = true;
}
}
}

}
调用方法如下:
dataGridViewEx1.TopRow.Cells[2].Text = "入库";
dataGridViewEx1.TopRow.Cells[2].ColSpan = 2;
dataGridViewEx1.TopRow.Cells[4].Text = "出库";
dataGridViewEx1.TopRow.Cells[4].ColSpan = 2;
然而这种方法我不确定可不可行,因为我不知道里面的topRow定义是什么,所以也就这方法不知道怎么实现了。
第二种方法是使用第三方控件,当然这需要money,估计很少有程序员说开发项目想花钱去买第三方控件的吧。
目前我知道的第三种方法,也是可行的方法就是网上的制作一个HeaderUnitView组件来实现。具体代码如下:
第三种方法原文地址:http://blog.sina.com.cn/s/blog_8388ce730100s4k6.html
表示已经使用过,其中已有现成的HeaderUnitView.dll可以下载
dll下载地址:csdn
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;
///
<summary>
///
水平滚动时是否刷新表头,数据较多时可能会闪烁,不刷新时可能显示错误
/// </summary>
[Description("水平滚动时是否刷新表头,数据较多时可能会闪烁,不刷新时可能显示错误")]
public bool RefreshAtHscroll
{
get {
return HscrollRefresh;
}
set {
HscrollRefresh = value; }
}
///
<summary>
///
构造函数
///
</summary>
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]; }
}
///
<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;
}
}
private List<string>
_mergecolumnname = new List<string>();
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)