DataGridView多维表头设置


通过:dataGridView1.TopLeftHeaderCell.Value = "表头\n回车";设置表头。
DataGridView实现多维表头

在做信息管理系统时,很多中式报表都是多维的,要实现报表数据显示,通常要用到多维表头。然而,非常遗憾的是,Winform中DataGrid、DataGridView本身不提供多维表头设计,要实现多维报表只好利用第三方的控件。通过对DataGridView的扩展,利用标题行进行重绘,可实现多维表头的友好界面。下面是对多维表头的探讨和实现。

1、常用多表头制作方法

     a.第三方控件实现多维表头:FlexGrid--展示效果很好,就是数据量大加载时显示速度较慢。

     b.报表方式实现多维表头:CrystalReport、Grid++Report--通过预览方式实现数据显示

     c、DataGridView实现多维表头

2、DataGridView多维表头实现原理

     通过重绘标题栏进行多栏实现,通过RowSpan和ColSpan来进行合并,类似Html的Table实现方式。

3、调用方法

        private  void Form1_Load( object sender, EventArgs e)
        {
            InitDataTable();
            InitDataGridView();
        }

        DataTable table =  new DataTable();

         private  void InitDataTable()
        {          

            DataColumn col;

            col =  new DataColumn();
            col.ColumnName =  " 客户名称 ";
            table.Columns.Add(col);

            col =  new DataColumn();
            col.ColumnName =  " 产品名称 ";
            table.Columns.Add(col);

            col =  new DataColumn();
            col.ColumnName =  " 规格 ";
            table.Columns.Add(col);

            col =  new DataColumn();
            col.ColumnName =  " 单位 ";
            table.Columns.Add(col);

            col =  new DataColumn();
            col.ColumnName =  " 期初存货数量 ";
            col.DataType = System.Type.GetType( " System.Decimal ");
            table.Columns.Add(col);

            col =  new DataColumn();
            col.ColumnName =  " 期初货款 ";
            col.DataType = System.Type.GetType( " System.Decimal ");
            table.Columns.Add(col);

            col =  new DataColumn();
            col.ColumnName =  " 期初帐款 ";
            col.DataType = System.Type.GetType( " System.Decimal ");
            table.Columns.Add(col);

            col =  new DataColumn();
            col.ColumnName =  " 发货数量 ";
            col.DataType = System.Type.GetType( " System.Decimal ");
            table.Columns.Add(col);

            col =  new DataColumn();
            col.ColumnName =  " 发货金额 ";
            col.DataType = System.Type.GetType( " System.Decimal ");
            table.Columns.Add(col);

            col =  new DataColumn();
            col.ColumnName =  " 开票数量 ";
            col.DataType = System.Type.GetType( " System.Decimal ");
            table.Columns.Add(col);

            col =  new DataColumn();
            col.ColumnName =  " 开票金额 ";
            col.DataType = System.Type.GetType( " System.Decimal ");
            table.Columns.Add(col);

            col =  new DataColumn();
            col.ColumnName =  " 回款数量 ";
            col.DataType = System.Type.GetType( " System.Decimal ");
            table.Columns.Add(col);

            col =  new DataColumn();
            col.DataType = System.Type.GetType( " System.Decimal ");
            col.ColumnName =  " 回款金额 ";
            table.Columns.Add(col);

            col =  new DataColumn();
            col.DataType = System.Type.GetType( " System.Decimal ");
            col.ColumnName =  " 未开票回款数量 ";
            table.Columns.Add(col);

            col =  new DataColumn();
            col.DataType = System.Type.GetType( " System.Decimal ");
            col.ColumnName =  " 未开票回款金额 ";
            table.Columns.Add(col);

            col =  new DataColumn();
            col.DataType = System.Type.GetType( " System.Decimal ");
            col.ColumnName =  " 期末存货数量 ";
            table.Columns.Add(col);

            col =  new DataColumn();
            col.DataType = System.Type.GetType( " System.Decimal ");
            col.ColumnName =  " 期末应收货款 ";
            table.Columns.Add(col);

            col =  new DataColumn();
            col.DataType = System.Type.GetType( " System.Decimal ");
            col.ColumnName =  " 期末应收帐款 ";
            table.Columns.Add(col);
        }

         private  void  InitDataGridView()
        {
            MutilGridHeader topRow =  new MutilGridHeader();
            topRow.SetRowCol( 318);

             // 第一行
            topRow.Cells[ 0][ 0].Value =  " 客户 ";
            topRow.Cells[ 0][ 0].RowSpan =  3;

            topRow.Cells[ 0][ 1].Value =  " 产品名称 ";
            topRow.Cells[ 0][ 1].RowSpan =  3;

            topRow.Cells[ 0][ 2].Value =  " 规格 ";
            topRow.Cells[ 0][ 2].RowSpan =  3;

            topRow.Cells[ 0][ 3].Value =  " 单位 ";
            topRow.Cells[ 0][ 3].RowSpan =  3;

            topRow.Cells[ 0][ 4].Value =  " 期初 ";
            topRow.Cells[ 0][ 4].ColSpan =  3;

            topRow.Cells[ 0][ 7].Value =  " 本期 ";
            topRow.Cells[ 0][ 7].ColSpan =  8;

            topRow.Cells[ 0][ 15].Value =  " 期末 ";
            topRow.Cells[ 0][ 15].ColSpan =  3;


             // 第二行
            topRow.Cells[ 1][ 4].Value =  " 存货数量 ";
            topRow.Cells[ 1][ 4].RowSpan =  2;

            topRow.Cells[ 1][ 5].Value =  " 应收货款 ";
            topRow.Cells[ 1][ 5].RowSpan =  2;

            topRow.Cells[ 1][ 6].Value =  " 应收帐款 ";
            topRow.Cells[ 1][ 6].RowSpan =  2;

            topRow.Cells[ 1][ 7].Value =  " 发货 ";
            topRow.Cells[ 1][ 7].ColSpan =  2;

            topRow.Cells[ 1][ 9].Value =  " 开票 ";
            topRow.Cells[ 1][ 9].ColSpan =  2;

            topRow.Cells[ 1][ 11].Value =  " 回款 ";
            topRow.Cells[ 1][ 11].ColSpan =  2;

            topRow.Cells[ 1][ 13].Value =  " 未开票回款 ";
            topRow.Cells[ 1][ 13].ColSpan =  2;

            topRow.Cells[ 1][ 15].Value =  " 存货数量 ";
            topRow.Cells[ 1][ 15].RowSpan =  2;

            topRow.Cells[ 1][ 16].Value =  " 应收货款 ";
            topRow.Cells[ 1][ 16].RowSpan =  2;

            topRow.Cells[ 1][ 17].Value =  " 应收票款 ";
            topRow.Cells[ 1][ 17].RowSpan =  2;

             // 第三行
            topRow.Cells[ 2][ 7].Value =  " 数量 ";
            topRow.Cells[ 2][ 8].Value =  " 金额 ";
            topRow.Cells[ 2][ 9].Value =  " 数量 ";
            topRow.Cells[ 2][ 10].Value =  " 金额 ";
            topRow.Cells[ 2][ 11].Value =  " 数量 ";
            topRow.Cells[ 2][ 12].Value =  " 金额 ";
            topRow.Cells[ 2][ 13].Value =  " 数量 ";
            topRow.Cells[ 2][ 14].Value =  " 金额 ";


            dataGridViewEx1.Header = topRow;
            dataGridViewEx1.DataSource = table;
            table.DefaultView.AllowNew =  false;

            dataGridViewEx1.Columns[ 0].Width =  120;
            dataGridViewEx1.Columns[ 1].Width =  100;
            dataGridViewEx1.Columns[ 2].Width =  80;
             for( int i =  2;i< 18;i++)
                dataGridViewEx1.Columns[i].Width =  60;

         }

Datagridview 实现二维表头
      最近把我们的b/s系统,增加智能客户端的功能。确实智能客户端是非常好用的东西。可惜winform的控件功能不怎么强大,相比vb差很多啊。比如DataGridView不支持二维表头,不支持表尾合计,相比之下 web的好办多了(还是喜欢Web的排版、导航,但喜欢Win的操作性,希望WPF早日流行)。

       但是 MIS系统没有二维表头确实是客户不能接受的,尝试了com控件flexgrid或者开源的SourceGrid3,但都不怎么好用,于是想改造一下DataGridView。我的做法是在CellPainting做手脚。花了一天时间尝试,只是做出原型,还没有完善,希望有需要的朋友少走弯路。

  1,继承DataGridView,添加表头信息类。
  2,添加CellPainting,代码如下:
   private   void  DataGridViewEx_CellPainting( object  sender, DataGridViewCellPaintingEventArgs e)
ExpandedBlockStart.gif        
{
            
if (e.RowIndex == -1)
ExpandedSubBlockStart.gif            
{
             
//   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))
ExpandedSubBlockStart.gif                
{
                    
using (Pen gridLinePen = new Pen(gridBrush))
ExpandedSubBlockStart.gif                    
{
                        
// 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)
ExpandedSubBlockStart.gif                        
{
                            e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right 
- 1,
                                e.CellBounds.Top 
+ e.ClipBounds.Height / 2, e.CellBounds.Right - 1,
                                e.CellBounds.Bottom);
                        }

                        
else
ExpandedSubBlockStart.gif                        
{
                            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)
ExpandedSubBlockStart.gif                        
{
                            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)
ExpandedSubBlockStart.gif                        
{
                            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)
                    
ExpandedSubBlockStart.gif                        
{
                            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;
                    }

                }

            }


        }

3,调用方法
  dataGridViewEx1.TopRow.Cells[ 2 ].Text  =   " 入库 " ;
            dataGridViewEx1.TopRow.Cells[
2 ].ColSpan  =   2 ;


            dataGridViewEx1.TopRow.Cells[
4 ].Text  =   " 出库 " ;
            dataGridViewEx1.TopRow.Cells[
4 ].ColSpan  =   2 ;
4,效果图

至于表尾合计,也做出了原型。二维表头+表尾合计,基本上满足需求了。
url: http://greatverve.cnblogs.com/archive/2012/07/17/TopLeftHeaderCell.html
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值