根据网上资料,进行实操后,得到上图,觉得还是挺不错的,
namespace MultiColHeaderDgvTest
{
partial class FrmTest
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("Node1");
System.Windows.Forms.TreeNode treeNode1_1 = new System.Windows.Forms.TreeNode("Node1_1", new System.Windows.Forms.TreeNode[] {
treeNode1});
System.Windows.Forms.TreeNode treeNode1_2 = new System.Windows.Forms.TreeNode("treeNode1_2", new System.Windows.Forms.TreeNode[] {
treeNode1_1 });
System.Windows.Forms.TreeNode treeNode1_3 = new System.Windows.Forms.TreeNode("treeNode1_3", new System.Windows.Forms.TreeNode[] {
treeNode1_2 });
System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode("Node2");
System.Windows.Forms.TreeNode treeNode2_1 = new System.Windows.Forms.TreeNode("treeNode2_1", new System.Windows.Forms.TreeNode[] {
treeNode2});
System.Windows.Forms.TreeNode treeNode3 = new System.Windows.Forms.TreeNode("treeNode3");
System.Windows.Forms.TreeNode treeNode3_1 = new System.Windows.Forms.TreeNode("treeNode3_1", new System.Windows.Forms.TreeNode[] {
treeNode3 });
System.Windows.Forms.TreeNode treeNode4 = new System.Windows.Forms.TreeNode("treeNode4");
System.Windows.Forms.TreeNode treeNode4_1 = new System.Windows.Forms.TreeNode("treeNode4_1", new System.Windows.Forms.TreeNode[] {
treeNode4});
System.Windows.Forms.TreeNode treeNode5 = new System.Windows.Forms.TreeNode("treeNode5");
System.Windows.Forms.TreeNode treeNode5_1 = new System.Windows.Forms.TreeNode("treeNode5_1", new System.Windows.Forms.TreeNode[] {
treeNode5});
System.Windows.Forms.TreeNode treeNode6 = new System.Windows.Forms.TreeNode("treeNode6");
System.Windows.Forms.TreeNode treeNode6_1 = new System.Windows.Forms.TreeNode("treeNode6_1", new System.Windows.Forms.TreeNode[] {
treeNode6});
System.Windows.Forms.TreeNode treeNode6_2 = new System.Windows.Forms.TreeNode("treeNode6_2", new System.Windows.Forms.TreeNode[] {
treeNode6_1});
System.Windows.Forms.TreeNode treeNode7 = new System.Windows.Forms.TreeNode("treeNode6");
System.Windows.Forms.TreeNode treeNode7_1 = new System.Windows.Forms.TreeNode("treeNode7_1", new System.Windows.Forms.TreeNode[] {
treeNode7});
System.Windows.Forms.TreeNode treeNode7_2 = new System.Windows.Forms.TreeNode("treeNode7_2", new System.Windows.Forms.TreeNode[] {
treeNode7_1});
System.Windows.Forms.TreeNode treeNode8 = new System.Windows.Forms.TreeNode("Node67", new System.Windows.Forms.TreeNode[] {
treeNode6_2,treeNode7_2});
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
this.treeView2 = new System.Windows.Forms.TreeView();
this.multiColHeaderDgv2 = new myMultiColHeaderDgv.MultiColHeaderDgv();
((System.ComponentModel.ISupportInitialize)(this.multiColHeaderDgv2)).BeginInit();
this.SuspendLayout();
//
// treeView2
//
this.treeView2.Location = new System.Drawing.Point(800, 26);
this.treeView2.Name = "treeView2";
treeNode1.Name = "Node1";
treeNode1.Text = "Node1";
treeNode2.Name = "Node2";
treeNode2.Text = "Node2";
treeNode1_3.Name = "treeNode1_3";
treeNode1_3.Text = "treeNode1_3";
treeNode4.Name = "Node4";
treeNode4.Text = "Node4";
this.treeView2.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
treeNode1_3,treeNode2_1,treeNode3_1,
treeNode4_1,treeNode5, treeNode8});
this.treeView2.Size = new System.Drawing.Size(600, 202);
this.treeView2.TabIndex = 3;
//
// multiColHeaderDgv2
//
this.multiColHeaderDgv2.AllowUserToAddRows = false;
this.multiColHeaderDgv2.AllowUserToDeleteRows = false;
this.multiColHeaderDgv2.AllowUserToResizeRows = false;
this.multiColHeaderDgv2.ColumnHeadersHeight = 18;
this.multiColHeaderDgv2.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
this.multiColHeaderDgv2.Location = new System.Drawing.Point(-2, 26);
this.multiColHeaderDgv2.myColHeaderTreeView = this.treeView2;
this.multiColHeaderDgv2.Name = "multiColHeaderDgv2";
this.multiColHeaderDgv2.RowTemplate.Height = 18;
this.multiColHeaderDgv2.Size = new System.Drawing.Size(760, 500);
this.multiColHeaderDgv2.TabIndex = 2;
//
// FrmTest
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 555);
// this.Controls.Add(this.treeView2);
this.Controls.Add(this.multiColHeaderDgv2);
this.Name = "FrmTest";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.multiColHeaderDgv2)).EndInit();
this.ResumeLayout(false);
}
#endregion
private myMultiColHeaderDgv.MultiColHeaderDgv multiColHeaderDgv2;
private System.Windows.Forms.TreeView treeView2;
}
}
编辑表头
public partial class FrmTest : Form
{
public FrmTest()
{
InitializeComponent();
DataTable dtable = new DataTable("Rock");
//set columns names
dtable.Columns.Add("Band", typeof(System.String));
dtable.Columns.Add("Song", typeof(System.String));
dtable.Columns.Add("Album", typeof(System.String));
dtable.Columns.Add("Album2", typeof(System.String));
dtable.Columns.Add("Album3", typeof(System.String));
dtable.Columns.Add("Album4", typeof(System.String));
dtable.Columns.Add("Album5", typeof(System.String));
//Add Rows
DataRow drow = dtable.NewRow();
drow["Band"] = "Iron Maiden";
drow["Song"] = "Wasted Years";
drow["Album"] = "Ed Hunter";
drow["Album2"] = "kG";
drow["Album3"] = "Hunter";
drow["Album4"] = "Hunter";
drow["Album5"] = "Hunter";
dtable.Rows.Add(drow);
multiColHeaderDgv2.DataSource = dtable;
}
用到调用的类,此类是网上而得
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
namespace myMultiColHeaderDgv
{
public class MultiColHeaderDgv : DataGridView
{
#region 字段定義
/// <summary>多維列標題的樹結構
///
/// </summary>
private TreeView _ColHeaderTreeView;
/// <summary>樹的最大層數
///
/// </summary>
private int iNodeLevels;
/// <summary>一維列標題的高度
///
/// </summary>
private int iCellHeight;
/// <summary>所有葉節點
///
/// </summary>
private IList<TreeNode> ColLists = new List<TreeNode>();
#endregion
#region 屬性定義
/// <summary>多維列標題的樹結構
///
/// </summary>
[
Description("多維列標題的樹結構")
]
public TreeView myColHeaderTreeView
{
get { return _ColHeaderTreeView; }
set { _ColHeaderTreeView = value; }
}
#endregion
#region 方法函數
/// <summary>遞歸計算樹最大層數,並保存所有葉節點
///
/// </summary>
/// <param name="tnc"></param>
/// <returns></returns>
private int myGetNodeLevels(TreeNodeCollection tnc)
{
if (tnc == null) return 0;
foreach (TreeNode tn in tnc)
{
if ((tn.Level + 1) > iNodeLevels)//tn.Level是從0開始的
{
iNodeLevels = tn.Level + 1;
}
if (tn.Nodes.Count > 0)
{
myGetNodeLevels(tn.Nodes);
}
else
{
ColLists.Add(tn);//葉節點
}
}
return iNodeLevels;
}
/// <summary>調用遞歸求最大層數、列頭總高
///
/// </summary>
public void myNodeLevels()
{
iNodeLevels = 1;//初始為1
ColLists.Clear();
int iNodeDeep = myGetNodeLevels(_ColHeaderTreeView.Nodes);
iCellHeight = this.ColumnHeadersHeight;
this.ColumnHeadersHeight = this.ColumnHeadersHeight * iNodeDeep;//列頭總高=一維列高*層數
}
/// <summary>获得合并标题字段的宽度
///
/// </summary>
/// <param name="node">字段节点</param>
/// <returns>字段宽度</returns>
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;
}
/// <summary>获得底层字段索引
///
/// </summary>
///' <param name="node">底层字段节点</param>
/// <returns>索引</returns>
/// <remarks></remarks>
private int GetColumnListNodeIndex(TreeNode node)
{
for (int i = 0; i <= ColLists.Count - 1; i++)
{
if (ColLists[i].Equals(node))
return i;
}
return -1;
}
///<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 * iCellHeight,
uhWidth - 1,
iCellHeight * (iNodeLevels - node.Level) - 1);
}
else
{
uhRectangle = new Rectangle(
e.CellBounds.Left,
e.CellBounds.Top + node.Level * iCellHeight,
uhWidth - 1,
iCellHeight - 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.ColumnHeadersDefaultCellStyle.Font
, Brushes.Black
, uhRectangle.Left + uhRectangle.Width / 2 -
e.Graphics.MeasureString(node.Text, this.ColumnHeadersDefaultCellStyle.Font).Width / 2 - 1
, uhRectangle.Top +
uhRectangle.Height / 2 - e.Graphics.MeasureString(node.Text, this.ColumnHeadersDefaultCellStyle.Font).Height / 2);
//递归调用()
if (node.PrevNode == null)
if (node.Parent != null)
PaintUnitHeader(node.Parent, e, level - 1);
}
#endregion
//重寫表頭
protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
{
try
{
//行标题不重写
if (e.ColumnIndex < 0)
{
base.OnCellPainting(e);
return;
}
if (iNodeLevels == 1)
{
base.OnCellPainting(e);
return;
}
//绘制表头
if (e.RowIndex == -1)
{
if (_ColHeaderTreeView != null)
{
if (iNodeLevels == 0)
{
myNodeLevels();
}
PaintUnitHeader((TreeNode)this.ColLists[e.ColumnIndex], e, iNodeLevels);
e.Handled = true;
}
else
{
base.OnCellPainting(e);
}
}
}
catch (Exception ex)
{
MessageBox.Show(this, ex.Message, "Error");
}
}
}
}
如果绑定textBox的话
则 this.Node1.DataPropertyName = "Node1";
this.Node1.HeaderText = "Node1";
this.Node1.Name = "Node1";