欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#自定義組件實現(xiàn)表格的多層表頭功能

 更新時間:2024年12月13日 10:22:18   作者:數(shù)據(jù)的世界01  
這篇文章主要為大家詳細介紹了如何使用C#自定義組件實現(xiàn)表格的多層表頭功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

在 WinForms 中,想要實現(xiàn)多層表頭功能時,DataGridView 本身并不支持該功能,而且又不希望使用第三方控件,因此選擇通過自定義組件來實現(xiàn)這一需求。

首先,展示一下程序?qū)崿F(xiàn)的效果:

接下來,創(chuàng)建一個繼承自 DataGridView 的自定義組件。代碼如下:

using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Drawing;
 
namespace CellPaintingDataGridView
{
    public partial class TreeHeadDataGridView : DataGridView
    {
        private TreeView treeView1=new TreeView();
        public TreeHeadDataGridView()
        {
            InitializeComponent();
        }
 
        public TreeHeadDataGridView(IContainer container)
        {
            container.Add(this);
 
            InitializeComponent();
        }
 
 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public TreeNodeCollection HeadSource
        {
            get { return this.treeView1.Nodes; }
 
        }
 
 
        private int _cellHeight = 17;
        private int _columnDeep = 1;
        [Description("設(shè)置或獲得合并表頭樹的深度")]
        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;
            }
        }
        
        ///<summary>
        ///繪制合并表頭
        ///</summary>
        ///<param name="node">合并表頭節(jié)點</param>
        ///<param name="e">繪圖參數(shù)集</param>
        ///<param name="level">結(jié)點深度</param>
        ///<remarks></remarks>
        public void PaintUnitHeader(TreeNode node, DataGridViewCellPaintingEventArgs e, int level)
        {
            //根節(jié)點時退出遞歸調(diào)用
            if (level == 0)
                return;
 
            RectangleF uhRectangle;
            int uhWidth;
            SolidBrush gridBrush = new SolidBrush(this.GridColor);
 
            Pen gridLinePen = new Pen(gridBrush);
            StringFormat textFormat = new StringFormat();
 
 
            textFormat.Alignment = StringAlignment.Center;
 
            uhWidth = GetUnitHeaderWidth(node);
 
            //與原貼算法有所區(qū)別在這。
            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);
            }
 
            Color backColor = e.CellStyle.BackColor;
            if (node.BackColor != Color.Empty)
            {
                backColor = node.BackColor;
            }
            SolidBrush backColorBrush = new SolidBrush(backColor);
            //畫矩形
            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);
 
            寫字段文本
            Color foreColor = Color.Black;
            if (node.ForeColor != Color.Empty)
            {
                foreColor = node.ForeColor;
            }
            e.Graphics.DrawString(node.Text, this.Font
                                    , new SolidBrush(foreColor)
                                    , 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);
 
            遞歸調(diào)用()
            if (node.PrevNode == null)
                if (node.Parent != null)
                    PaintUnitHeader(node.Parent, e, level - 1);
        }
 
        /// <summary>
        /// 獲得合并標題字段的寬度
        /// </summary>
        /// <param name="node">字段節(jié)點</param>
        /// <returns>字段寬度</returns>
        /// <remarks></remarks>
        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">底層字段節(jié)點</param>
        /// <returns>索引</returns>
        /// <remarks></remarks>
        private int GetColumnListNodeIndex(TreeNode node)
        {
            for (int i = 0; i <= _columnList.Count - 1; i++)
            {
                if (((TreeNode)_columnList[i]).Equals(node))
                    return i;
            }
            return -1;
        }
 
        private List<TreeNode> _columnList = new List<TreeNode>();
        [Description("最底層結(jié)點集合")]
        public List<TreeNode> NadirColumnList
        {
            get
            {
                if (this.treeView1 == null)
                    return null;
 
                if (this.treeView1.Nodes == null)
                    return null;
 
                if (this.treeView1.Nodes.Count == 0)
                    return null;
 
                _columnList.Clear();
                foreach (TreeNode node in this.treeView1.Nodes)
                {
                    //GetNadirColumnNodes(_columnList, node, false);
                    GetNadirColumnNodes(_columnList, node);
                }
                return _columnList;
            }
        }
 
        private void GetNadirColumnNodes(List<TreeNode> alList, TreeNode node)
        {
            if (node.FirstNode == null)
            {
                alList.Add(node);
            }
            foreach (TreeNode n in node.Nodes)
            {
                GetNadirColumnNodes(alList, n);
            }
        }
 
        /// <summary>
        /// 獲得底層字段集合
        /// </summary>
        /// <param name="alList">底層字段集合</param>
        /// <param name="node">字段節(jié)點</param>
        /// <param name="checked">向上搜索與否</param>
        /// <remarks></remarks>
        private void GetNadirColumnNodes(List<TreeNode> alList, TreeNode node, Boolean isChecked)
        {
            if (isChecked == false)
            {
                if (node.FirstNode == null)
                {
                    alList.Add(node);
                    if (node.NextNode != null)
                    {
                        GetNadirColumnNodes(alList, node.NextNode, false);
                        return;
                    }
                    if (node.Parent != null)
                    {
                        GetNadirColumnNodes(alList, node.Parent, true);
                        return;
                    }
                }
                else
                {
                    if (node.FirstNode != null)
                    {
                        GetNadirColumnNodes(alList, node.FirstNode, false);
                        return;
                    }
                }
            }
            else
            {
                if (node.FirstNode == null)
                {
                    return;
                }
                else
                {
                    if (node.NextNode != null)
                    {
                        GetNadirColumnNodes(alList, node.NextNode, false);
                        return;
                    }
 
                    if (node.Parent != null)
                    {
                        GetNadirColumnNodes(alList, node.Parent, true);
                        return;
                    }
                }
            }
        }
 
        /// <summary>
        /// 單元格繪制(重寫)
        /// </summary>
        /// <param name="e"></param>
        /// <remarks></remarks>
        protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
        {
            //行標題不重寫
            if (e.ColumnIndex < 0)
            {
                base.OnCellPainting(e);
                return;
            }
 
            if (_columnDeep == 1)
            {
                base.OnCellPainting(e);
                return;
            }
 
            //繪制表頭
            if (e.RowIndex == -1)
            {
                PaintUnitHeader((TreeNode)NadirColumnList[e.ColumnIndex], e, _columnDeep);
                e.Handled = true;
            }
        }
 
    }
}

完成組件開發(fā)后,可以將該控件從工具箱拖入界面,表頭的節(jié)點設(shè)置通過 Designer.cs 中的 "Windows 窗體設(shè)計器生成的代碼" 實現(xiàn)。我們使用 System.Windows.Forms.TreeNode 來實現(xiàn)父子節(jié)點的綁定。示例代碼如下:

namespace CellPaintingDataGridView
{
    partial class Form1
    {
        /// <summary>
        /// 必需的設(shè)計器變量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;
 
        /// <summary>
        /// 清理所有正在使用的資源。
        /// </summary>
        /// <param name="disposing">如果應(yīng)釋放托管資源,為 true;否則為 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
 
        #region Windows 窗體設(shè)計器生成的代碼
 
        /// <summary>
        /// 設(shè)計器支持所需的方法 - 不要
        /// 使用代碼編輯器修改此方法的內(nèi)容。
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("節(jié)點0");
            System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode("節(jié)點1-0-0");
            System.Windows.Forms.TreeNode treeNode3 = new System.Windows.Forms.TreeNode("節(jié)點1-0-1");
            System.Windows.Forms.TreeNode treeNode4 = new System.Windows.Forms.TreeNode("節(jié)點1-0", new System.Windows.Forms.TreeNode[] {
            treeNode2,
            treeNode3});
            System.Windows.Forms.TreeNode treeNode5 = new System.Windows.Forms.TreeNode("節(jié)點1-1");
            System.Windows.Forms.TreeNode treeNode6 = new System.Windows.Forms.TreeNode("節(jié)點1", new System.Windows.Forms.TreeNode[] {
            treeNode4,
            treeNode5});
            System.Windows.Forms.TreeNode treeNode7 = new System.Windows.Forms.TreeNode("節(jié)點2-0");
            System.Windows.Forms.TreeNode treeNode8 = new System.Windows.Forms.TreeNode("節(jié)點2-1");
            System.Windows.Forms.TreeNode treeNode9 = new System.Windows.Forms.TreeNode("節(jié)點2-0");
            System.Windows.Forms.TreeNode treeNode10 = new System.Windows.Forms.TreeNode("節(jié)點2", new System.Windows.Forms.TreeNode[] {
            treeNode7,
            treeNode8,
            treeNode9});
            System.Windows.Forms.TreeNode treeNode11 = new System.Windows.Forms.TreeNode("節(jié)點3-0");
            System.Windows.Forms.TreeNode treeNode12 = new System.Windows.Forms.TreeNode("節(jié)點3-1");
            System.Windows.Forms.TreeNode treeNode13 = new System.Windows.Forms.TreeNode("節(jié)點3", new System.Windows.Forms.TreeNode[] {
            treeNode11,
            treeNode12});
            this.treeHeadDataGridView1 = new CellPaintingDataGridView.TreeHeadDataGridView(this.components);
            this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Column2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Column3 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Column4 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Column5 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Column6 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Column7 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Column8 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Column9 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            ((System.ComponentModel.ISupportInitialize)(this.treeHeadDataGridView1)).BeginInit();
            this.SuspendLayout();
            // 
            // treeHeadDataGridView1
            // 
            this.treeHeadDataGridView1.ColumnDeep = 3;
            this.treeHeadDataGridView1.ColumnHeadersHeight = 51;
            this.treeHeadDataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
            this.treeHeadDataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
            this.Column1,
            this.Column2,
            this.Column3,
            this.Column4,
            this.Column5,
            this.Column6,
            this.Column7,
            this.Column8,
            this.Column9});
            treeNode1.Name = "節(jié)點";
            treeNode1.Text = "節(jié)點0";
            treeNode2.Name = "節(jié)點1-0-0";
            treeNode2.Text = "節(jié)點1-0-0";
            treeNode3.Name = "節(jié)點1-0-1";
            treeNode3.Text = "節(jié)點1-0-1";
            treeNode4.Name = "節(jié)點1-0";
            treeNode4.Text = "節(jié)點1-0";
            treeNode5.Name = "節(jié)點1-1";
            treeNode5.Text = "節(jié)點1-1";
            treeNode6.Name = "節(jié)點1";
            treeNode6.Text = "節(jié)點1";
            treeNode7.Name = "節(jié)點2-0";
            treeNode7.Text = "節(jié)點2-0";
            treeNode8.Name = "節(jié)點2-1";
            treeNode8.Text = "節(jié)點2-1";
            treeNode9.Name = "節(jié)點2-0";
            treeNode9.Text = "節(jié)點2-0";
            treeNode10.Name = "節(jié)點2";
            treeNode10.Text = "節(jié)點2";
            treeNode11.Name = "節(jié)點3-0";
            treeNode11.Text = "節(jié)點3-0";
            treeNode12.Name = "節(jié)點3-1";
            treeNode12.Text = "節(jié)點3-1";
            treeNode13.Name = "節(jié)點3";
            treeNode13.Text = "節(jié)點3";
            this.treeHeadDataGridView1.HeadSource.AddRange(new System.Windows.Forms.TreeNode[] {
            treeNode1,
            treeNode6,
            treeNode10,
            treeNode13});
            this.treeHeadDataGridView1.Location = new System.Drawing.Point(12, 12);
            this.treeHeadDataGridView1.Name = "treeHeadDataGridView1";
            this.treeHeadDataGridView1.RowTemplate.Height = 23;
            this.treeHeadDataGridView1.Size = new System.Drawing.Size(1034, 456);
            this.treeHeadDataGridView1.TabIndex = 0;
            // 
            // Column1
            // 
            this.Column1.HeaderText = "Column1";
            this.Column1.Name = "Column1";
            this.Column1.Width = 110;
            // 
            // Column2
            // 
            this.Column2.FillWeight = 80F;
            this.Column2.HeaderText = "Column2";
            this.Column2.Name = "Column2";
            // 
            // Column3
            // 
            this.Column3.FillWeight = 60F;
            this.Column3.HeaderText = "Column3";
            this.Column3.Name = "Column3";
            this.Column3.Width = 160;
            // 
            // Column4
            // 
            this.Column4.HeaderText = "Column4";
            this.Column4.Name = "Column4";
            // 
            // Column5
            // 
            this.Column5.HeaderText = "Column5";
            this.Column5.Name = "Column5";
            // 
            // Column6
            // 
            this.Column6.HeaderText = "Column6";
            this.Column6.Name = "Column6";
            // 
            // Column7
            // 
            this.Column7.HeaderText = "Column7";
            this.Column7.Name = "Column7";
            // 
            // Column8
            // 
            this.Column8.HeaderText = "Column8";
            this.Column8.Name = "Column8";
            // 
            // Column9
            // 
            this.Column9.HeaderText = "Column9";
            this.Column9.Name = "Column9";
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(1077, 533);
            this.Controls.Add(this.treeHeadDataGridView1);
            this.Name = "Form1";
            this.Text = "Form1";
            ((System.ComponentModel.ISupportInitialize)(this.treeHeadDataGridView1)).EndInit();
            this.ResumeLayout(false);
 
        }
 
        #endregion
 
        private TreeHeadDataGridView treeHeadDataGridView1;
        private System.Windows.Forms.DataGridViewTextBoxColumn Column1;
        private System.Windows.Forms.DataGridViewTextBoxColumn Column2;
        private System.Windows.Forms.DataGridViewTextBoxColumn Column3;
        private System.Windows.Forms.DataGridViewTextBoxColumn Column4;
        private System.Windows.Forms.DataGridViewTextBoxColumn Column5;
        private System.Windows.Forms.DataGridViewTextBoxColumn Column6;
        private System.Windows.Forms.DataGridViewTextBoxColumn Column7;
        private System.Windows.Forms.DataGridViewTextBoxColumn Column8;
        private System.Windows.Forms.DataGridViewTextBoxColumn Column9;
    }
}

通過這種方式,我們成功實現(xiàn)了多層表頭的功能,完全依賴自定義組件,不需要第三方控件。

到此這篇關(guān)于C#自定義組件實現(xiàn)表格的多層表頭功能的文章就介紹到這了,更多相關(guān)C#多層表頭內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C# Distinct和重寫IEqualityComparer時要知道的二三事

    C# Distinct和重寫IEqualityComparer時要知道的二三事

    這篇文章主要給大家介紹了關(guān)于C# Distinct和重寫IEqualityComparer時要知道的二三事,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • windows下C#定時管理器框架Task.MainForm詳解

    windows下C#定時管理器框架Task.MainForm詳解

    這篇文章主要為大家詳細介紹了windows下C#定時管理器框架Task.MainForm的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 深入理解C♯ 7.0中的Tuple特性

    深入理解C♯ 7.0中的Tuple特性

    這篇文章主要介紹了C#7中Tuple特性的相關(guān)資料,文中通過示例代碼介紹的非常詳細,相信對大家具有一定的參考價值,需要的朋友可以們下面來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-03-03
  • C# AutoResetEvent的具體使用方法

    C# AutoResetEvent的具體使用方法

    AutoResetEvent是C#中的一個同步原語,用于在線程之間傳遞信號,本文主要介紹了C# AutoResetEvent的具體使用方法,具有一定的參考價值,感興趣的可以了解一下
    2025-01-01
  • c# 進程和線程的區(qū)別與聯(lián)系

    c# 進程和線程的區(qū)別與聯(lián)系

    這篇文章主要介紹了c# 進程和線程的區(qū)別與聯(lián)系,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2020-12-12
  • Unity實現(xiàn)主角移動與攝像機跟隨

    Unity實現(xiàn)主角移動與攝像機跟隨

    這篇文章主要為大家詳細介紹了Unity實現(xiàn)主角移動與攝像機跟隨,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • C#實現(xiàn)觀察者模式(Observer?Pattern)的兩種方式

    C#實現(xiàn)觀察者模式(Observer?Pattern)的兩種方式

    這篇文章介紹了C#實現(xiàn)觀察者模式(Observer?Pattern)的兩種方式,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08
  • C#語法糖(Csharp Syntactic sugar)大匯總

    C#語法糖(Csharp Syntactic sugar)大匯總

    首先需要聲明的是“語法糖”這個詞絕非貶義詞,它可以給我?guī)矸奖悖且环N便捷的寫法,編譯器會幫我們做轉(zhuǎn)換;而且可以提高開發(fā)編碼的效率,在性能上也不會帶來損失。這讓java開發(fā)人員羨慕不已,呵呵。
    2010-06-06
  • Unity3D運行報DllNotFoundException錯誤的解決方案

    Unity3D運行報DllNotFoundException錯誤的解決方案

    這篇文章主要介紹了Unity3D運行報DllNotFoundException錯誤的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • C# BeginInvoke實現(xiàn)異步編程方式

    C# BeginInvoke實現(xiàn)異步編程方式

    這篇文章主要介紹了C# BeginInvoke實現(xiàn)異步編程方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01

最新評論