如何实现DATAGRIDVIEW的多维表头的问题。.net控件达人进来看一看吧

时间:2022-08-31 14:13:32
我做的项目当要实现DATAGRIDVIEW的多维表头,在网上看到有人重写的DATAGRIDVIEW控件HeaderUnitView.cs,但是容易花掉,和出错,考虑到代码的安全性不知道.NET控件达人人有没有什么好的方法以共参考以下呢。。。HELP  达人们````

46 个解决方案

#1


http://www.programfan.com/wysoft/showwysoft.asp?id=3390 看看能不能用

#2


自定义GridView的表头

有时候会遇到这种情况,一个表格,显示的数据只是简单的行列,但是表头比较复杂,跨行、跨列都有出现。

这样复杂的表头是无法在GridView中直接定义出来的,还不想用Table、TableRow和TableCell像打砖块一样一层层地去拼凑出个表格来,所以就要想办法自定义GridView的表头了。其实GridView有个对象成员HeaderRow,它就是GridView的表头行,对它进行操作,就可以实现自定义的表头了。

假设页面上有一个ID为gridResult的GridView,像这样:

//清空表头行的原有的单元格
         gridResult.HeaderRow.Cells.Clear();
         //新建一个单元格
         TableCell cell = new TableCell();
         //注意下面的HTML的写法
         cell.Text = "标题1</td><td colspan='2'>标题2</td><td rowspan='2'>标题3</td></tr><tr><td>标题11</td><td>标题21</td><td>标题22";
         gridResult.HeaderRow.Cells.Add(cell);

这样运行后会在页面上生成一个类似这样的表格:

标题1 标题2 标题3
标题11 标题21 标题22
1 2 3 4
但是这个表头是相对比较简单的,如果再复杂一些,比如有几十个甚至上百个列的情况,并且需要有比较复杂的样式设置,这种直接拼合HTML字符串的方法可能有点力不从心了,一个比较简单的方法是,在页面上定义画一个Table,包含表头需要的所有列及样式,然后在代码中实时取得这个Table的Row的HTML源代码(关于在代码中取得Table的HTML代码,可以参考 asp.net导出文件,支持中文文件名 和 在从GridView导出时Excel报错),再用上面的方法加入到GridView的表头中就可以了,需要注意的是自定义的HTML与GridView生成的HTML的整合,这个可以尽量发挥自己的想象了,没有最好只有更好!

#3


假设页面上有一个ID为GridView1的GridView,
    //清空表头行的原有的单元格
         GridView1.HeaderRow.Cells.Clear();
         //新建一个单元格
         TableCell cell = new TableCell();
         cell.Text = "标题1</td><td >标题2</td><td>标题3</td>   
     //添加新的表头                      
     GridView1.HeaderRow.Cells.Add(cell);
这样就可以生成 标题1 标题2 标题3 作为表头了

#4



<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" BorderWidth="1" Width="100%" BorderColor="#93BEE2" BorderStyle="Solid" CellPadding="0" Font-Size="12px" ForeColor="Black" PageIndex="0" AllowPaging=true PageSize="15" OnPageIndexChanging="GridView1_PageIndexChanging" OnRowCreated="GridView1_RowCreated">
   <Columns>
       <asp:BoundField HeaderText="全宗号" DataField="WholeID" />
       <asp:BoundField HeaderText="全宗名称" DataField="WholeName" />
       <asp:BoundField HeaderText="目录启止号" DataField="MenuStartEndID" />
       <asp:BoundField HeaderText="启止年代" DataField="StartEndDatetime" />
       <asp:BoundField HeaderText="合计档案" DataField="ThisTotal" />
       <asp:BoundField HeaderText="永久档案" DataField="ThisForever" />
       <asp:BoundField HeaderText="长期档案" DataField="ThisLong" />
       <asp:BoundField HeaderText="短期档案" DataField="ThisShort" />
       <asp:BoundField HeaderText="存放位置" DataField="SavePlace" />
       <%--<asp:BoundField HeaderText="档案信息存储数字化情况" DataField="AsNumber" />--%>
       <asp:TemplateField HeaderText="档案信息存储数字化情况">
                        <ItemTemplate>
                            <%# (DataBinder.Eval(Container.DataItem, "AsNumber").ToString().Length > 10) ? DataBinder.Eval(Container.DataItem, "AsNumber").ToString().Substring(0, 10) + "..." : DataBinder.Eval(Container.DataItem, "AsNumber").ToString()%>
                        </ItemTemplate>
        </asp:TemplateField>
       <%--<asp:BoundField HeaderText="备注" DataField="Remark" />--%>
             <asp:TemplateField HeaderText="备注">
                        <ItemTemplate>
                            <%# (DataBinder.Eval(Container.DataItem, "Remark").ToString().Length > 10) ? DataBinder.Eval(Container.DataItem, "Remark").ToString().Substring(0, 10) + "..." : DataBinder.Eval(Container.DataItem, "Remark").ToString()%>
                        </ItemTemplate>
        </asp:TemplateField>
       <asp:TemplateField HeaderText="操作">
           <ItemTemplate>
           <div style="text-align:center">
               <a href="CartularyWholeStatisticEdit.aspx?CartularyWholeStatisticID=<%# DataBinder.Eval(Container, "DataItem.CartularyWholeStatisticID")%>&PageIndex=<%=PageIndex%>">编辑</a>&nbsp;<a onclick="return delconfirm()" href="CartularyWholeStatisticDele.aspx?CartularyWholeStatisticID=<%# DataBinder.Eval(Container, "DataItem.CartularyWholeStatisticID")%>&PageIndex=<%=PageIndex%>">删除</a>
           </div>
           </ItemTemplate>
           <ItemStyle Width="100px" />
       </asp:TemplateField>
   </Columns>
   <HeaderStyle BackColor="#337FB2" Font-Bold="False" Font-Size="12px" ForeColor="White" Height="22px" />
   <RowStyle Height="22px" Font-Size="12px" HorizontalAlign=Center />
   <AlternatingRowStyle Height="22px" BackColor="#E8F4FF" />
   <PagerStyle HorizontalAlign="Right" />
</asp:GridView>
////////////////////////////////////
  

#5


楼上的我说的是winform 里面的datagridview,你说的是WEB的。

#6


哪位置达人有没有好的源码文件发我油箱286733953@qq.com.  最好效率高的 ,不用到递归和TreeView,谢谢达人们了  

#7


UP

#8


教我啊  怎么做都可以  

#9


自己帮顶 devexpress  这个第三方控件有人用过吗 我想用他来试一试

#10


http://download.csdn.net/down/286788/li_wei_888呵呵!来看看这个吧!一定没问题的!

#11


我用DEV控件,但是不清楚LZ要实现什么具体的功能。

#12


devexpress里面的GridManager是可以实现多维表头的功能,但它也有一个局限性,这个局限性在什么地方呢,用语言表达很罗嗦,在此略过.我前段时间的一个项目就需要做多维表头,一个是重写DataGridView,用GDI+画表头,定义什么TreeView,麻烦死了.后来又用Devexpress发现可以做多维表头,但它设置有问题,最后没办法了,直接用多个DataGridView拼多维表头了,只要设置好了他们的布局就可以了!效果看上去跟真的复合表头一样!

#13


devexpress里面的GridManager是可以实现多维表头的功能,但它也有一个局限性,这个局限性在什么地方呢,用语言表达很罗嗦,在此略过.我前段时间的一个项目就需要做多维表头,一个是重写DataGridView,用GDI+画表头,定义什么TreeView,麻烦死了.后来又用Devexpress发现可以做多维表头,但它设置有问题,最后没办法了,直接用多个DataGridView拼多维表头了,只要设置好了他们的布局就可以了!效果看上去跟真的复合表头一样!

#14


引用 9 楼 hnjhjzyyxgs 的回复:
自己帮顶 devexpress  这个第三方控件有人用过吗 我想用他来试一试 

用这个比较好,自带例子。

#15


引用 13 楼 ycsno1 的回复:
devexpress里面的GridManager是可以实现多维表头的功能,但它也有一个局限性,这个局限性在什么地方呢,用语言表达很罗嗦,在此略过.我前段时间的一个项目就需要做多维表头,一个是重写DataGridView,用GDI+画表头,定义什么TreeView,麻烦死了.后来又用Devexpress发现可以做多维表头,但它设置有问题,最后没办法了,直接用多个DataGridView拼多维表头了,只要设置好了他们的布局就可以了!效果看上去跟真的复合表头一样!

大哥你是如何拼装的啊 说来听听。。

#16


引用 10 楼 liudeqing2008 的回复:
http://download.csdn.net/down/286788/li_wei_888呵呵!来看看这个吧!一定没问题的!

这个我看过了,是DLL文件,每次用着DLL文件都会跳出个对话筐要我跟他联系,怎么放到项目里面去呢。。。。

#17


达人们  有好的办法吗?

#18


ding

#19


http://download.csdn.net/down/967997/yinzl_85

#20



DataGridView表头合并
 /// <summary>
    /// 合并表头
    /// </summary>
    public class HeaderGridView
    {
        #region 合并Header 创建表头区域的使用到的位置和大小属性

        int cTop = 0;//被合并表头区域的顶部Y坐标 
        int cLeft = 0;//被合并表头区域的左边X坐标        
        int cWidth = 0;   // 被合并表头区域的宽 
        int cHeight = 0;//。。。高       

        #endregion


        //  private HeaderGridView() { }

        private HeaderGridView() { }


        #region single mode

        private static object m_lock_object = new object();
        private static HeaderGridView m_header;
        public static Hashtable hs = new Hashtable();
        public static HeaderGridView GetSingle()
        {
            if (m_header == null)
            {
                lock (m_lock_object)
                {
                    if (m_header == null)
                    {
                        m_header = new HeaderGridView();

                    }
                }
            }
            return m_header;
        }

        #endregion

        /// <summary> 
        /// 合并表头,用在dataGridView的CellPainting事件中。 
        /// </summary> 
        /// <param name="sender">需要重绘的dataGridview</param> 
        /// <param name="e">CellPainting中的参数</param> 
        ///<param name="colName">列的集合(列必须是连续的,第一列放在最前面)</param> 
        /// <param name="headerText">列合并后显示的文本</param> 
        public void MergeHeader(object sender, DataGridViewCellPaintingEventArgs e, List<string> colNameCollection, string headerText)
        {
            if (e.RowIndex == -1 && e.ColumnIndex != -1)
            {
                DataGridView dataGridView1 = sender as DataGridView;
                string colName = dataGridView1.Columns[e.ColumnIndex].Name;

                //0.扩展表头高度为当前的2倍 
                if (!hs.Contains(dataGridView1.Name))
                {
                    hs.Add(dataGridView1.Name, "0");
                    dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
                    dataGridView1.ColumnHeadersHeight = e.CellBounds.Height * 2;
                }

                if (colNameCollection.Contains(colName))
                {
                    #region 重绘列头
                    //1.计算colLen个列的区域 
                    if (colNameCollection.IndexOf(colName) == 0)
                    {
                        cTop = e.CellBounds.Top;
                        cLeft = e.CellBounds.Left;

                        cWidth = e.CellBounds.Width;
                        cHeight = e.CellBounds.Height / 2;
                        //求总的合并列的宽度
                        foreach (string colNameItem in colNameCollection)
                        {
                            if (colNameItem.Equals(colName))
                            {//除去自己一个,加了之后colLen-1个列的宽 
                                continue;
                            }
                            cWidth += dataGridView1.Columns[colNameItem].Width;
                        }
                    }
                    if (colNameCollection.IndexOf(colName) == 0)
                    {
                        Rectangle cArea = new Rectangle(cLeft, cTop, cWidth, cHeight);
                        //2.把区域设置为背景色,没有列的分线及任何文字。 
                        using (Brush backColorBrush = new SolidBrush(e.CellStyle.BackColor))
                        {
                            e.Graphics.FillRectangle(backColorBrush, cArea);

                        }
                    }
                   

#21




 if (colNameCollection.IndexOf(colName) == 0)
                    {
                        //3.绘制新列头的边框 
                        using (Pen gridPen = new Pen(dataGridView1.GridColor))
                        {
                            //3.1 上部边框 
                            e.Graphics.DrawLine(gridPen, cLeft, cTop, cLeft + cWidth, cTop);
                            using (Pen hilightPen = new Pen(Color.WhiteSmoke))
                            {
                                //3.2 顶部高光 
                                e.Graphics.DrawLine(hilightPen, cLeft, cTop + 1, cLeft + cWidth, cTop + 1);
                                //3.3 左部反光线 
                                e.Graphics.DrawLine(hilightPen, cLeft, cTop + 3, cLeft, cTop + cHeight - 2);
                            }
                            //3.4 下部边框 
                            e.Graphics.DrawLine(gridPen, cLeft, cTop + cHeight - 1, cLeft + cWidth, cTop + cHeight - 1);
                            //3.5 右部边框                         
                            e.Graphics.DrawLine(gridPen, cLeft + cWidth - 1, cTop, cLeft + cWidth - 1, cTop + cHeight);//(cTop+cHeight)/2); 
                        }
                    }

                    //4.Header 写文本 
                    if (colNameCollection.IndexOf(colName) == 0)
                    {//不是第一列则不写文字。

                        int wHeadStr = (int)(headerText.Length * e.CellStyle.Font.SizeInPoints);
                        int wHeadCell = cWidth;
                        int pHeadLeft = (wHeadCell - wHeadStr) / 2 - 6;
                        using (Brush foreBrush = new SolidBrush(e.CellStyle.ForeColor))
                        {
                            e.Graphics.DrawString(headerText, e.CellStyle.Font, foreBrush, new PointF(cLeft + pHeadLeft, cTop + 3));
                        }
                    }


                    ////5 绘制子列背景 
                    int FatherColHeight = e.CellBounds.Height / 2;//上面一行的高度  
                    using (Brush backColorBrush = new SolidBrush(e.CellStyle.BackColor))
                    {
                        e.Graphics.FillRectangle(backColorBrush, new Rectangle(e.CellBounds.X, e.CellBounds.Y + FatherColHeight, e.CellBounds.Width - 1, e.CellBounds.Height / 2 - 1));
                    }
                    ////5.1绘制子列的边框

                    using (Pen gridPen = new Pen(dataGridView1.GridColor))
                    {
                        using (Pen hilightPen = new Pen(Color.WhiteSmoke))
                        {
                            //5.2 左部反光线 
                            e.Graphics.DrawLine(hilightPen, cLeft, cTop + 3 + FatherColHeight, cLeft, cTop + cHeight - 2 + FatherColHeight);
                        }
                        //5.3 下部边框 
                        e.Graphics.DrawLine(gridPen, cLeft, cTop + cHeight - 1 + FatherColHeight, cLeft + cWidth, cTop + cHeight - 1 + FatherColHeight);

                        //5.4 右部边框  
                        e.Graphics.DrawLine(gridPen, e.CellBounds.X + e.CellBounds.Width - 1, e.CellBounds.Top + FatherColHeight, e.CellBounds.X + e.CellBounds.Width - 1, e.CellBounds.Top + e.CellBounds.Height + FatherColHeight);//(cTop+cHeight)/2);                    

                    }
                    //5.5 写子列的文本 
                    int wStr = (int)(dataGridView1.Columns[e.ColumnIndex].HeaderText.Length * e.CellStyle.Font.SizeInPoints);
                    int wCell = e.CellBounds.Width;
                    int pLeft = (wCell - wStr) / 2;//相对CELL左边框的左坐标

                    using (Brush foreBrush = new SolidBrush(e.CellStyle.ForeColor))
                    {
                        e.Graphics.DrawString(dataGridView1.Columns[e.ColumnIndex].HeaderText, e.CellStyle.Font, foreBrush, new PointF(e.CellBounds.X + pLeft, cTop + 3 + FatherColHeight));
                    }

                    #endregion
                    e.Handled = true; //系统继续处理
                }
            }
        }

        /// <summary>
        /// 扩展表头高度为当前的2倍
        /// </summary>
        /// <param name="sender"></param>
        public void HeightHeader(object sender, DataGridViewCellPaintingEventArgs e)
        {
            DataGridView dataGridView1 = sender as DataGridView;
            if (!hs.Contains(dataGridView1.Name))
            {
                hs.Add(dataGridView1.Name, "0");
                dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
                dataGridView1.ColumnHeadersHeight = e.CellBounds.Height * 2;
            }
        }
    }

#22




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


至于表尾合计,也做出了原型。二维表头+表尾合计,基本上满足需求了。

#23


http://www.codesky.net/article/doc/200804/2008042180945345.htm

http://download.csdn.net/down/967997/yinzl_85

#24


关注ing

#25


这方面一直,没有深入,帮顶,期待高效简洁的解决方式

#26


学习

#27


直接在页面上先正常的使用GRIDVIEW控件,然后在一个TABLE里合并表头。然后页面用VB处理一下就可以。这样的话合并表头后可以继续使用排序。我尝试过在.CS里合并表头但是实现不了排序功能。

#28


引用 27 楼 apurt 的回复:
直接在页面上先正常的使用GRIDVIEW控件,然后在一个TABLE里合并表头。然后页面用VB处理一下就可以。这样的话合并表头后可以继续使用排序。我尝试过在.CS里合并表头但是实现不了排序功能。

WINFORM 中有TABLE 吗?

#29


这样行不?下面用一个list上面加一些按钮或其它的控件当表头,比较灵活了吧。

#30


先mark

#31


帮顶。

#32


敢问哪里有这个程序的截图吗,不太明白各位达人到底实现了什么,关注中......

#33


这么多达人就没有一个好的解决方案吗?

#34


怎么都用GRIDVIEW.

#35


顶啊  问题没有解决帖子决不能沉啊~

#36


CS模式里怎么弄,关注,BS楼上说了

#37


顶啊  问题没有解决帖子决不能沉啊~

#38


风雨不是说的很详细了?

#39


使用devexpress控件,页面放一个Grid,然后run designer -> Views -> Cleck Hear to -> convert to -> BandedGridViews
这样就把GridView转换成了双层表头,你可以点band进行表头的设定,次表头对应的列
我也不知道我理解的是不是你所要的东西,暂且回个帖,希望对你有帮助

#41


引用 40 楼 wuyq11 的回复:
或使用第三方控件 
http://www.cnblogs.com/hehuaflower/archive/2009/02/28/1400188.html
效率积低,非常容易出错,用在项目中很危险。没有用

#42


学习

#43


关注,帮顶~~

#44


学习

#45


谁能有好的方案实例,不要用到递归等  发到我的油箱xiaojunyonglb@163.com   
http://topic.csdn.net/u/20090318/00/f271b9ee-7427-4bf6-89d8-ccaf00de235f.html
http://topic.csdn.net/u/20090318/00/e5137518-f2b5-4d81-8d4f-3acbbb87e681.html
http://topic.csdn.net/u/20090309/16/be37aff1-dadf-4a80-976a-49e0971af6ba.html
三个问题的分全给你 一共550分!!!!!!!!!!

#46


该回复于2011-03-11 14:27:15被版主删除

#1


http://www.programfan.com/wysoft/showwysoft.asp?id=3390 看看能不能用

#2


自定义GridView的表头

有时候会遇到这种情况,一个表格,显示的数据只是简单的行列,但是表头比较复杂,跨行、跨列都有出现。

这样复杂的表头是无法在GridView中直接定义出来的,还不想用Table、TableRow和TableCell像打砖块一样一层层地去拼凑出个表格来,所以就要想办法自定义GridView的表头了。其实GridView有个对象成员HeaderRow,它就是GridView的表头行,对它进行操作,就可以实现自定义的表头了。

假设页面上有一个ID为gridResult的GridView,像这样:

//清空表头行的原有的单元格
         gridResult.HeaderRow.Cells.Clear();
         //新建一个单元格
         TableCell cell = new TableCell();
         //注意下面的HTML的写法
         cell.Text = "标题1</td><td colspan='2'>标题2</td><td rowspan='2'>标题3</td></tr><tr><td>标题11</td><td>标题21</td><td>标题22";
         gridResult.HeaderRow.Cells.Add(cell);

这样运行后会在页面上生成一个类似这样的表格:

标题1 标题2 标题3
标题11 标题21 标题22
1 2 3 4
但是这个表头是相对比较简单的,如果再复杂一些,比如有几十个甚至上百个列的情况,并且需要有比较复杂的样式设置,这种直接拼合HTML字符串的方法可能有点力不从心了,一个比较简单的方法是,在页面上定义画一个Table,包含表头需要的所有列及样式,然后在代码中实时取得这个Table的Row的HTML源代码(关于在代码中取得Table的HTML代码,可以参考 asp.net导出文件,支持中文文件名 和 在从GridView导出时Excel报错),再用上面的方法加入到GridView的表头中就可以了,需要注意的是自定义的HTML与GridView生成的HTML的整合,这个可以尽量发挥自己的想象了,没有最好只有更好!

#3


假设页面上有一个ID为GridView1的GridView,
    //清空表头行的原有的单元格
         GridView1.HeaderRow.Cells.Clear();
         //新建一个单元格
         TableCell cell = new TableCell();
         cell.Text = "标题1</td><td >标题2</td><td>标题3</td>   
     //添加新的表头                      
     GridView1.HeaderRow.Cells.Add(cell);
这样就可以生成 标题1 标题2 标题3 作为表头了

#4



<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" BorderWidth="1" Width="100%" BorderColor="#93BEE2" BorderStyle="Solid" CellPadding="0" Font-Size="12px" ForeColor="Black" PageIndex="0" AllowPaging=true PageSize="15" OnPageIndexChanging="GridView1_PageIndexChanging" OnRowCreated="GridView1_RowCreated">
   <Columns>
       <asp:BoundField HeaderText="全宗号" DataField="WholeID" />
       <asp:BoundField HeaderText="全宗名称" DataField="WholeName" />
       <asp:BoundField HeaderText="目录启止号" DataField="MenuStartEndID" />
       <asp:BoundField HeaderText="启止年代" DataField="StartEndDatetime" />
       <asp:BoundField HeaderText="合计档案" DataField="ThisTotal" />
       <asp:BoundField HeaderText="永久档案" DataField="ThisForever" />
       <asp:BoundField HeaderText="长期档案" DataField="ThisLong" />
       <asp:BoundField HeaderText="短期档案" DataField="ThisShort" />
       <asp:BoundField HeaderText="存放位置" DataField="SavePlace" />
       <%--<asp:BoundField HeaderText="档案信息存储数字化情况" DataField="AsNumber" />--%>
       <asp:TemplateField HeaderText="档案信息存储数字化情况">
                        <ItemTemplate>
                            <%# (DataBinder.Eval(Container.DataItem, "AsNumber").ToString().Length > 10) ? DataBinder.Eval(Container.DataItem, "AsNumber").ToString().Substring(0, 10) + "..." : DataBinder.Eval(Container.DataItem, "AsNumber").ToString()%>
                        </ItemTemplate>
        </asp:TemplateField>
       <%--<asp:BoundField HeaderText="备注" DataField="Remark" />--%>
             <asp:TemplateField HeaderText="备注">
                        <ItemTemplate>
                            <%# (DataBinder.Eval(Container.DataItem, "Remark").ToString().Length > 10) ? DataBinder.Eval(Container.DataItem, "Remark").ToString().Substring(0, 10) + "..." : DataBinder.Eval(Container.DataItem, "Remark").ToString()%>
                        </ItemTemplate>
        </asp:TemplateField>
       <asp:TemplateField HeaderText="操作">
           <ItemTemplate>
           <div style="text-align:center">
               <a href="CartularyWholeStatisticEdit.aspx?CartularyWholeStatisticID=<%# DataBinder.Eval(Container, "DataItem.CartularyWholeStatisticID")%>&PageIndex=<%=PageIndex%>">编辑</a>&nbsp;<a onclick="return delconfirm()" href="CartularyWholeStatisticDele.aspx?CartularyWholeStatisticID=<%# DataBinder.Eval(Container, "DataItem.CartularyWholeStatisticID")%>&PageIndex=<%=PageIndex%>">删除</a>
           </div>
           </ItemTemplate>
           <ItemStyle Width="100px" />
       </asp:TemplateField>
   </Columns>
   <HeaderStyle BackColor="#337FB2" Font-Bold="False" Font-Size="12px" ForeColor="White" Height="22px" />
   <RowStyle Height="22px" Font-Size="12px" HorizontalAlign=Center />
   <AlternatingRowStyle Height="22px" BackColor="#E8F4FF" />
   <PagerStyle HorizontalAlign="Right" />
</asp:GridView>
////////////////////////////////////
  

#5


楼上的我说的是winform 里面的datagridview,你说的是WEB的。

#6


哪位置达人有没有好的源码文件发我油箱286733953@qq.com.  最好效率高的 ,不用到递归和TreeView,谢谢达人们了  

#7


UP

#8


教我啊  怎么做都可以  

#9


自己帮顶 devexpress  这个第三方控件有人用过吗 我想用他来试一试

#10


http://download.csdn.net/down/286788/li_wei_888呵呵!来看看这个吧!一定没问题的!

#11


我用DEV控件,但是不清楚LZ要实现什么具体的功能。

#12


devexpress里面的GridManager是可以实现多维表头的功能,但它也有一个局限性,这个局限性在什么地方呢,用语言表达很罗嗦,在此略过.我前段时间的一个项目就需要做多维表头,一个是重写DataGridView,用GDI+画表头,定义什么TreeView,麻烦死了.后来又用Devexpress发现可以做多维表头,但它设置有问题,最后没办法了,直接用多个DataGridView拼多维表头了,只要设置好了他们的布局就可以了!效果看上去跟真的复合表头一样!

#13


devexpress里面的GridManager是可以实现多维表头的功能,但它也有一个局限性,这个局限性在什么地方呢,用语言表达很罗嗦,在此略过.我前段时间的一个项目就需要做多维表头,一个是重写DataGridView,用GDI+画表头,定义什么TreeView,麻烦死了.后来又用Devexpress发现可以做多维表头,但它设置有问题,最后没办法了,直接用多个DataGridView拼多维表头了,只要设置好了他们的布局就可以了!效果看上去跟真的复合表头一样!

#14


引用 9 楼 hnjhjzyyxgs 的回复:
自己帮顶 devexpress  这个第三方控件有人用过吗 我想用他来试一试 

用这个比较好,自带例子。

#15


引用 13 楼 ycsno1 的回复:
devexpress里面的GridManager是可以实现多维表头的功能,但它也有一个局限性,这个局限性在什么地方呢,用语言表达很罗嗦,在此略过.我前段时间的一个项目就需要做多维表头,一个是重写DataGridView,用GDI+画表头,定义什么TreeView,麻烦死了.后来又用Devexpress发现可以做多维表头,但它设置有问题,最后没办法了,直接用多个DataGridView拼多维表头了,只要设置好了他们的布局就可以了!效果看上去跟真的复合表头一样!

大哥你是如何拼装的啊 说来听听。。

#16


引用 10 楼 liudeqing2008 的回复:
http://download.csdn.net/down/286788/li_wei_888呵呵!来看看这个吧!一定没问题的!

这个我看过了,是DLL文件,每次用着DLL文件都会跳出个对话筐要我跟他联系,怎么放到项目里面去呢。。。。

#17


达人们  有好的办法吗?

#18


ding

#19


http://download.csdn.net/down/967997/yinzl_85

#20



DataGridView表头合并
 /// <summary>
    /// 合并表头
    /// </summary>
    public class HeaderGridView
    {
        #region 合并Header 创建表头区域的使用到的位置和大小属性

        int cTop = 0;//被合并表头区域的顶部Y坐标 
        int cLeft = 0;//被合并表头区域的左边X坐标        
        int cWidth = 0;   // 被合并表头区域的宽 
        int cHeight = 0;//。。。高       

        #endregion


        //  private HeaderGridView() { }

        private HeaderGridView() { }


        #region single mode

        private static object m_lock_object = new object();
        private static HeaderGridView m_header;
        public static Hashtable hs = new Hashtable();
        public static HeaderGridView GetSingle()
        {
            if (m_header == null)
            {
                lock (m_lock_object)
                {
                    if (m_header == null)
                    {
                        m_header = new HeaderGridView();

                    }
                }
            }
            return m_header;
        }

        #endregion

        /// <summary> 
        /// 合并表头,用在dataGridView的CellPainting事件中。 
        /// </summary> 
        /// <param name="sender">需要重绘的dataGridview</param> 
        /// <param name="e">CellPainting中的参数</param> 
        ///<param name="colName">列的集合(列必须是连续的,第一列放在最前面)</param> 
        /// <param name="headerText">列合并后显示的文本</param> 
        public void MergeHeader(object sender, DataGridViewCellPaintingEventArgs e, List<string> colNameCollection, string headerText)
        {
            if (e.RowIndex == -1 && e.ColumnIndex != -1)
            {
                DataGridView dataGridView1 = sender as DataGridView;
                string colName = dataGridView1.Columns[e.ColumnIndex].Name;

                //0.扩展表头高度为当前的2倍 
                if (!hs.Contains(dataGridView1.Name))
                {
                    hs.Add(dataGridView1.Name, "0");
                    dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
                    dataGridView1.ColumnHeadersHeight = e.CellBounds.Height * 2;
                }

                if (colNameCollection.Contains(colName))
                {
                    #region 重绘列头
                    //1.计算colLen个列的区域 
                    if (colNameCollection.IndexOf(colName) == 0)
                    {
                        cTop = e.CellBounds.Top;
                        cLeft = e.CellBounds.Left;

                        cWidth = e.CellBounds.Width;
                        cHeight = e.CellBounds.Height / 2;
                        //求总的合并列的宽度
                        foreach (string colNameItem in colNameCollection)
                        {
                            if (colNameItem.Equals(colName))
                            {//除去自己一个,加了之后colLen-1个列的宽 
                                continue;
                            }
                            cWidth += dataGridView1.Columns[colNameItem].Width;
                        }
                    }
                    if (colNameCollection.IndexOf(colName) == 0)
                    {
                        Rectangle cArea = new Rectangle(cLeft, cTop, cWidth, cHeight);
                        //2.把区域设置为背景色,没有列的分线及任何文字。 
                        using (Brush backColorBrush = new SolidBrush(e.CellStyle.BackColor))
                        {
                            e.Graphics.FillRectangle(backColorBrush, cArea);

                        }
                    }
                   

#21




 if (colNameCollection.IndexOf(colName) == 0)
                    {
                        //3.绘制新列头的边框 
                        using (Pen gridPen = new Pen(dataGridView1.GridColor))
                        {
                            //3.1 上部边框 
                            e.Graphics.DrawLine(gridPen, cLeft, cTop, cLeft + cWidth, cTop);
                            using (Pen hilightPen = new Pen(Color.WhiteSmoke))
                            {
                                //3.2 顶部高光 
                                e.Graphics.DrawLine(hilightPen, cLeft, cTop + 1, cLeft + cWidth, cTop + 1);
                                //3.3 左部反光线 
                                e.Graphics.DrawLine(hilightPen, cLeft, cTop + 3, cLeft, cTop + cHeight - 2);
                            }
                            //3.4 下部边框 
                            e.Graphics.DrawLine(gridPen, cLeft, cTop + cHeight - 1, cLeft + cWidth, cTop + cHeight - 1);
                            //3.5 右部边框                         
                            e.Graphics.DrawLine(gridPen, cLeft + cWidth - 1, cTop, cLeft + cWidth - 1, cTop + cHeight);//(cTop+cHeight)/2); 
                        }
                    }

                    //4.Header 写文本 
                    if (colNameCollection.IndexOf(colName) == 0)
                    {//不是第一列则不写文字。

                        int wHeadStr = (int)(headerText.Length * e.CellStyle.Font.SizeInPoints);
                        int wHeadCell = cWidth;
                        int pHeadLeft = (wHeadCell - wHeadStr) / 2 - 6;
                        using (Brush foreBrush = new SolidBrush(e.CellStyle.ForeColor))
                        {
                            e.Graphics.DrawString(headerText, e.CellStyle.Font, foreBrush, new PointF(cLeft + pHeadLeft, cTop + 3));
                        }
                    }


                    ////5 绘制子列背景 
                    int FatherColHeight = e.CellBounds.Height / 2;//上面一行的高度  
                    using (Brush backColorBrush = new SolidBrush(e.CellStyle.BackColor))
                    {
                        e.Graphics.FillRectangle(backColorBrush, new Rectangle(e.CellBounds.X, e.CellBounds.Y + FatherColHeight, e.CellBounds.Width - 1, e.CellBounds.Height / 2 - 1));
                    }
                    ////5.1绘制子列的边框

                    using (Pen gridPen = new Pen(dataGridView1.GridColor))
                    {
                        using (Pen hilightPen = new Pen(Color.WhiteSmoke))
                        {
                            //5.2 左部反光线 
                            e.Graphics.DrawLine(hilightPen, cLeft, cTop + 3 + FatherColHeight, cLeft, cTop + cHeight - 2 + FatherColHeight);
                        }
                        //5.3 下部边框 
                        e.Graphics.DrawLine(gridPen, cLeft, cTop + cHeight - 1 + FatherColHeight, cLeft + cWidth, cTop + cHeight - 1 + FatherColHeight);

                        //5.4 右部边框  
                        e.Graphics.DrawLine(gridPen, e.CellBounds.X + e.CellBounds.Width - 1, e.CellBounds.Top + FatherColHeight, e.CellBounds.X + e.CellBounds.Width - 1, e.CellBounds.Top + e.CellBounds.Height + FatherColHeight);//(cTop+cHeight)/2);                    

                    }
                    //5.5 写子列的文本 
                    int wStr = (int)(dataGridView1.Columns[e.ColumnIndex].HeaderText.Length * e.CellStyle.Font.SizeInPoints);
                    int wCell = e.CellBounds.Width;
                    int pLeft = (wCell - wStr) / 2;//相对CELL左边框的左坐标

                    using (Brush foreBrush = new SolidBrush(e.CellStyle.ForeColor))
                    {
                        e.Graphics.DrawString(dataGridView1.Columns[e.ColumnIndex].HeaderText, e.CellStyle.Font, foreBrush, new PointF(e.CellBounds.X + pLeft, cTop + 3 + FatherColHeight));
                    }

                    #endregion
                    e.Handled = true; //系统继续处理
                }
            }
        }

        /// <summary>
        /// 扩展表头高度为当前的2倍
        /// </summary>
        /// <param name="sender"></param>
        public void HeightHeader(object sender, DataGridViewCellPaintingEventArgs e)
        {
            DataGridView dataGridView1 = sender as DataGridView;
            if (!hs.Contains(dataGridView1.Name))
            {
                hs.Add(dataGridView1.Name, "0");
                dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
                dataGridView1.ColumnHeadersHeight = e.CellBounds.Height * 2;
            }
        }
    }

#22




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


至于表尾合计,也做出了原型。二维表头+表尾合计,基本上满足需求了。

#23


http://www.codesky.net/article/doc/200804/2008042180945345.htm

http://download.csdn.net/down/967997/yinzl_85

#24


关注ing

#25


这方面一直,没有深入,帮顶,期待高效简洁的解决方式

#26


学习

#27


直接在页面上先正常的使用GRIDVIEW控件,然后在一个TABLE里合并表头。然后页面用VB处理一下就可以。这样的话合并表头后可以继续使用排序。我尝试过在.CS里合并表头但是实现不了排序功能。

#28


引用 27 楼 apurt 的回复:
直接在页面上先正常的使用GRIDVIEW控件,然后在一个TABLE里合并表头。然后页面用VB处理一下就可以。这样的话合并表头后可以继续使用排序。我尝试过在.CS里合并表头但是实现不了排序功能。

WINFORM 中有TABLE 吗?

#29


这样行不?下面用一个list上面加一些按钮或其它的控件当表头,比较灵活了吧。

#30


先mark

#31


帮顶。

#32


敢问哪里有这个程序的截图吗,不太明白各位达人到底实现了什么,关注中......

#33


这么多达人就没有一个好的解决方案吗?

#34


怎么都用GRIDVIEW.

#35


顶啊  问题没有解决帖子决不能沉啊~

#36


CS模式里怎么弄,关注,BS楼上说了

#37


顶啊  问题没有解决帖子决不能沉啊~

#38


风雨不是说的很详细了?

#39


使用devexpress控件,页面放一个Grid,然后run designer -> Views -> Cleck Hear to -> convert to -> BandedGridViews
这样就把GridView转换成了双层表头,你可以点band进行表头的设定,次表头对应的列
我也不知道我理解的是不是你所要的东西,暂且回个帖,希望对你有帮助

#40


#41


引用 40 楼 wuyq11 的回复:
或使用第三方控件 
http://www.cnblogs.com/hehuaflower/archive/2009/02/28/1400188.html
效率积低,非常容易出错,用在项目中很危险。没有用

#42


学习

#43


关注,帮顶~~

#44


学习

#45


谁能有好的方案实例,不要用到递归等  发到我的油箱xiaojunyonglb@163.com   
http://topic.csdn.net/u/20090318/00/f271b9ee-7427-4bf6-89d8-ccaf00de235f.html
http://topic.csdn.net/u/20090318/00/e5137518-f2b5-4d81-8d4f-3acbbb87e681.html
http://topic.csdn.net/u/20090309/16/be37aff1-dadf-4a80-976a-49e0971af6ba.html
三个问题的分全给你 一共550分!!!!!!!!!!

#46


该回复于2011-03-11 14:27:15被版主删除