关于双行表头的的DataGridView的实现

这个实现,视觉效果方面基本上没有问题了,不过执行速度还有很大提升的空间(比如,我不加区分的每次画主标题就浪费了很多时间)。但引入Timer控件的使用,刷新时闪烁的问题已经完美解决,本着“够用就行”的原则我不打算改进了...

代码:应该可以这样直接帖的,试试

      

  ///   <summary> 

        ///   支持双行表头的的DataGridView 

        ///   

        ///   用法示例: 

        ///   dg.AddSpanHeader(4,   4,   "主标题 "); 

        ///   则将第4列开始的4列设为双行表头,主标题为“主标题”,子标题为原来的   Value   值 

        ///   

        ///   phommy@hotmail.com 

        ///   </summary> 

        public   partial   class   DataGridViewEx1   :   DataGridView 

        { 

                public   DataGridViewEx1() 

                { 

                        InitializeComponent(); 

                } 

                protected   override   void   OnPaint(PaintEventArgs   pe) 

                { 

                        //   TODO:   在此处添加自定义绘制代码 



                        //   调用基类   OnPaint 

                        base.OnPaint(pe); 

                } 

                private   struct   SpanInfo     //表头信息 

                { 

                        public   SpanInfo(string   Text,   int   Position,   int   Left,   int   Right) 

                        { 

                                this.Text   =   Text; 

                                this.Position   =   Position; 

                                this.Left   =   Left; 

                                this.Right   =   Right; 

                        } 



                        public   string   Text;           //列主标题 

                        public   int   Position;         //位置,1:左,2中,3右 

                        public   int   Left;                 //对应左行 

                        public   int   Right;               //对应右行 

                } 



                private   Dictionary <int,   SpanInfo>   SpanRows   =   new   Dictionary <int,   SpanInfo> ();//需要2维表头的列 

                public   void   AddSpanHeader(int   ColIndex,   int   ColCount,   string   Text) 

                { 

                        if   (ColCount   <   2) 

                                throw   new   Exception( "行宽应大于等于2,合并1列无意义。 "); 



                        //检查范围 

                        for   (int   i   =   0;   i   <   ColCount;   i++) 

                        { 

                                if   (SpanRows.ContainsKey(ColIndex   +   i)) 

                                        throw   new   Exception( "单元格范围重叠! "); 

                        } 



                        //将这些列加入列表 

                        int   Right   =   ColIndex   +   ColCount   -   1;         //同一大标题下的最后一列的索引 

                        SpanRows[ColIndex]   =   new   SpanInfo(Text,   1,   ColIndex,   Right);         //添加标题下的最左列 

                        SpanRows[Right]   =   new   SpanInfo(Text,   3,   ColIndex,   Right);       //添加该标题下的最右列 

                        for   (int   i   =   ColIndex   +   1;   i   <   Right;   i++)     //中间的列 

                        { 

                                SpanRows[i]   =   new   SpanInfo(Text,   2,   ColIndex,   Right); 

                        } 

                } 



                public   void   ClearSpanInfo() 

                { 

                        SpanRows.Clear(); 

                        //ReDrawHead(); 

                } 



                private   void   DataGridViewEx_CellPainting(object   sender,   DataGridViewCellPaintingEventArgs   e) 

                { 

                        if   (e.RowIndex   ==   -1) 

                        { 

                                if   (SpanRows.ContainsKey(e.ColumnIndex))     //被合并的列 

                                { 

                                        //画边框 

                                        Graphics   g   =   e.Graphics; 

                                        e.Paint(e.CellBounds,   DataGridViewPaintParts.Background   |   DataGridViewPaintParts.Border); 



                                        int   left   =   e.CellBounds.Left,   top   =   e.CellBounds.Top   +   2, 

                                                right   =   e.CellBounds.Right,   bottom   =   e.CellBounds.Bottom; 



                                        switch   (SpanRows[e.ColumnIndex].Position) 

                                        { 

                                                case   1: 

                                                        left   +=   2; 

                                                        break; 

                                                case   2: 

                                                        break; 

                                                case   3: 

                                                        right   -=   2; 

                                                        break; 

                                        } 



                                        //画上半部分底色 

                                        g.FillRectangle(new   SolidBrush(e.CellStyle.BackColor),   left,   top, 

                                                right   -   left,   (bottom   -   top)   /   2); 



                                        //画中线 

                                        g.DrawLine(new   Pen(this.GridColor),   left,   (top   +   bottom)   /   2, 

                                                right,   (top   +   bottom)   /   2); 



                                        //写小标题 

                                        StringFormat   sf   =   new   StringFormat(); 

                                        sf.Alignment   =   StringAlignment.Center; 

                                        sf.LineAlignment   =   StringAlignment.Center; 



                                        g.DrawString(e.Value   +   " ",   e.CellStyle.Font,   Brushes.Black, 

                                        new   Rectangle(left,   (top   +   bottom)   /   2,   right   -   left,   (bottom   -   top)   /   2),   sf); 



                                        //写大标题 

                                        //if   (this.SpanRows[e.ColumnIndex].Position==3) 

                                        { 

                                                left   =   this.GetColumnDisplayRectangle(SpanRows[e.ColumnIndex].Left,   true).Left   -   2; 



                                                if   (left   <   0)   left   =   this.GetCellDisplayRectangle(-1,   -1,   true).Width; 

                                                right   =   this.GetColumnDisplayRectangle(SpanRows[e.ColumnIndex].Right,   true).Right   -   2; 

                                                if   (right   <   0)   right   =   this.Width; 



                                                g.DrawString(SpanRows[e.ColumnIndex].Text,   e.CellStyle.Font,   Brushes.Black, 

                                                        new   Rectangle(left,   top,   right   -   left,   (bottom   -   top)   /   2),   sf); 

                                        } 

                                        e.Handled   =   true; 

                                } 

                        } 

                } 

                private   void   DataGridViewEx_Scroll(object   sender,   ScrollEventArgs   e) 

                { 



                        if   (e.ScrollOrientation   ==   ScrollOrientation.HorizontalScroll)//   &&   e.Type   ==   ScrollEventType.EndScroll) 

                        { 

                                timer1.Enabled   =   false;   timer1.Enabled   =   true; 

                        } 

                } 



                //刷新显示表头 

                public   void   ReDrawHead() 

                { 

                        foreach   (int   si   in   SpanRows.Keys) 

                        { 

                                this.Invalidate(this.GetCellDisplayRectangle(si,   -1,   true)); 

                        } 

                } 



                private   void   timer1_Tick(object   sender,   EventArgs   e) 

                { 

                        timer1.Enabled   =   false; 

                        ReDrawHead(); 

                }///   <summary> 

                ///   必需的设计器变量。 

                ///   </summary> 

                private   System.ComponentModel.IContainer   components   =   null; 



                ///   <summary> 

                ///   清理所有正在使用的资源。 

                ///   </summary> 

                ///   <param   name= "disposing "> 如果应释放托管资源,为   true;否则为   false。 </param> 

                protected   override   void   Dispose(bool   disposing) 

                { 

                        if   (disposing   &&   (components   !=   null)) 

                        { 

                                components.Dispose(); 

                        } 

                        base.Dispose(disposing); 

                } 



                #region   组件设计器生成的代码 



                ///   <summary> 

                ///   设计器支持所需的方法   -   不要 

                ///   使用代码编辑器修改此方法的内容。 

                ///   </summary> 

                private   void   InitializeComponent() 

                { 

                        this.components   =   new   System.ComponentModel.Container(); 

                        this.timer1   =   new   System.Windows.Forms.Timer(this.components); 

                        ((System.ComponentModel.ISupportInitialize)(this)).BeginInit(); 

                        this.SuspendLayout(); 

                        //   

                        //   timer1 

                        //   

                        this.timer1.Interval   =   20; 

                        this.timer1.Tick   +=   new   System.EventHandler(this.timer1_Tick); 

                        //   

                        //   DataGridViewEx1 

                        //   

                        this.RowTemplate.Height   =   23; 

                        this.CellPainting   +=   new   System.Windows.Forms.DataGridViewCellPaintingEventHandler(this.DataGridViewEx_CellPainting); 

                        this.Scroll   +=   new   System.Windows.Forms.ScrollEventHandler(this.DataGridViewEx_Scroll); 

                        ((System.ComponentModel.ISupportInitialize)(this)).EndInit(); 

                        this.ResumeLayout(false); 



                } 

                #endregion 



                private   System.Windows.Forms.Timer   timer1; 

        }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在 WinForms 的 DataGridView 控件中,可以通过使用 ColumnHeader 属性来实现表头。具体步骤如下: 1. 设置控件的 ColumnHeadersVisible 属性为 false,这将隐藏默认的表头。 2. 添加自定义表头。可以使用 DataGridViewColumn 对象来创建列,然后使用 DataGridView.Columns.Add 方法将列添加到控件中。每个列可以包含一个或多个子列,用于创建自定义表头。 3. 设置每个列的 HeaderCell 属性为 DataGridViewColumnHeaderCell 对象。这将使该列的默认表头与自定义表头分离。 4. 设置每个子列的 HeaderCell 属性为 DataGridViewColumnHeaderCell 对象。这将使该子列的默认表头与自定义表头分离,并将其添加到相应的列中。 下面是一个简单的示例代码,用于创建一个带有两个表头DataGridView 控件: ```csharp // 隐藏默认表头 dataGridView1.ColumnHeadersVisible = false; // 创建第一级表头 DataGridViewColumn column1 = new DataGridViewTextBoxColumn(); column1.HeaderText = "表头1"; column1.Name = "Column1"; dataGridView1.Columns.Add(column1); // 创建第二级表头 DataGridViewColumn subColumn1 = new DataGridViewTextBoxColumn(); subColumn1.HeaderText = "子表头1"; subColumn1.Name = "SubColumn1"; DataGridViewColumn subColumn2 = new DataGridViewTextBoxColumn(); subColumn2.HeaderText = "子表头2"; subColumn2.Name = "SubColumn2"; column1.HeaderCell = new DataGridViewColumnHeaderCell(); column1.HeaderCell.Value = "表头1"; column1.HeaderCell.Style.Font = new Font(dataGridView1.Font, FontStyle.Bold); column1.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter; column1.HeaderCell.Style.BackColor = Color.LightGray; column1.HeaderCell.Style.WrapMode = DataGridViewTriState.True; column1.HeaderCell.Style.Padding = new Padding(2, 2, 2, 2); column1.HeaderCell.Style.SelectionBackColor = Color.DarkGray; column1.HeaderCell.Style.SelectionForeColor = Color.White; column1.HeaderCell.Style.SelectionBorderWidth = 2; column1.HeaderCell.Style.SelectionBorderColor = Color.Black; column1.HeaderCell.Style.SelectionFont = new Font(dataGridView1.Font, FontStyle.Bold); column1.HeaderCell.Style.SelectionAlignment = DataGridViewContentAlignment.MiddleCenter; subColumn1.HeaderCell = new DataGridViewColumnHeaderCell(); subColumn1.HeaderCell.Value = "子表头1"; subColumn2.HeaderCell = new DataGridViewColumnHeaderCell(); subColumn2.HeaderCell.Value = "子表头2"; column1.DataGridView.Columns.AddRange(new DataGridViewColumn[] { subColumn1, subColumn2 }); ``` 在这个示例中,我们创建了一个带有两个表头DataGridView 控件,并将其添加到窗体上。第一级表头为“表头1”,第二级表头包含两个子列:“子表头1”和“子表头2”。我们还设置了一些样式属性,以更改表头的外观和行为。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值