C#的多行表头,用TreeView实现,如图所示

如图

根据网上资料,进行实操后,得到上图,觉得还是挺不错的,

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

猜你喜欢

转载自blog.csdn.net/penghao_1/article/details/83039376
今日推荐