控件中国网现已改版,您看到的是老版本网站的镜像,系统正在为您跳转到新网站首页,请稍候.......
中国最专业的商业控件资讯网产品咨询电话:023-67870900 023-67871946
产品咨询EMAIL:SALES@COMPONENTCN.COM

动态列的GridView嵌套解决方法整理

作者:佚名 出处:互联网 2010年04月14日 阅读:

动态列的GridView嵌套解决方法整理

控件中国网为客户提供大量报表控件。

最近使用GridView做报表时遇到一个问题,在老大帮助下完成。现在记录一下。

项目需求类似如下的嵌套:

(例如一个借还系统,父级是借设备人的资料,子级是具体设备资料)

-------------------------

父编号   姓名   年龄

1         张三    20

      ----------------

      子编号   产品类型    产品名称

       1          路由器       凌凯    

      ----------------

2        李四      24

--------------------------

 

1.在一级数据的列数固定的情况下可直接使用如下嵌套:

基本思路是在行绑定事件中绑定嵌套的GridView2,这里如果GrideView2是动态列也可以,后台也能动态添加进去。

 

前台:

代码
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false"
            onrowdatabound="GridView1_RowDataBound">
        <Columns>
        <asp:TemplateField HeaderText="编号">
        <ItemTemplate><%#Eval("id") %></ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="姓名">
        <ItemTemplate><%#Eval("name") %></ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="年龄" >
        <ItemTemplate><%#Eval("age") %></ItemTemplate>
        </asp:TemplateField>
       
        <asp:TemplateField>       
        <ItemTemplate>   
      <tr colspan="3">   
            <asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="false">
            <Columns>
            <asp:TemplateField HeaderText="编号">
            <ItemTemplate><%#Eval("id") %></ItemTemplate>
            </asp:TemplateField>
           
            <asp:TemplateField HeaderText="类型">
            <ItemTemplate><%#Eval("type") %></ItemTemplate>
            </asp:TemplateField>
           
            <asp:TemplateField HeaderText="名称">
            <ItemTemplate><%#Eval("name") %></ItemTemplate>
            </asp:TemplateField>
            </Columns>
            </asp:GridView>
      </tr>
        </ItemTemplate>
        </asp:TemplateField>                
        </Columns>
        </asp:GridView>
 

 

后台:

代码
protected void Page_Load(object sender, EventArgs e)
    {
        DataTable dt = new DataTable();
        dt.Columns.Add("id");
        dt.Columns.Add("name");
        dt.Columns.Add("age");
        for (int i = 0; i < 3;i++ )
        {
            dt.Rows.Add(i.ToString(),"用户"+i,20+i);
        }
        DataSet ds = new DataSet();
        ds.Tables.Add(dt);
        this.GridView1.DataSource = ds;
        this.GridView1.DataBind();

    }
    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            GridView gv = e.Row.FindControl("GridView2") as GridView;
            DataTable dt = new DataTable();
            dt.Columns.Add("id");
            dt.Columns.Add("name");
            dt.Columns.Add("type");
            for (int i = 0; i < 3; i++)
            {
                dt.Rows.Add(i.ToString(), "产品" + i, "产品" + i);
            }
            DataSet ds = new DataSet();
            ds.Tables.Add(dt);
            gv.DataSource = ds;
            gv.DataBind();
        }
    }
 

 

2,一级数据的行中含有动态列

 

开始考虑是动态的加列就可以了,我们在Page_Load事件中增加下面代码:

代码
    for (int i = 0; i < 2;i++ )//向模板列中插入几列
        {
            BoundField bf = new BoundField();
            bf.HeaderText = "测试"+i;
            bf.DataField = "name";
            this.GridView1.Columns.Insert(1,bf);
        }
 

编号 测试1 测试0 姓名 年龄  
0 用户0 用户0 用户0 20 
此时动态列增加上了,但是分页时在行绑定事件中已经找不到嵌套的GridView2了,原因我现在还不知道,请知道的朋友告知一下。
编号 类型 名称
0 产品0 产品0
1 产品1 产品1
2 产品2 产品2
1用户1用户1用户121

编号 类型 名称
0 产品0 产品0
1 产品1 产品1
2 产品2 产品2

 

于是,到这里就想到自己写一个模板类了,控制更好一些,在写的过程中老大给了帮助,模板如下

 

代码
#region MyTemplate
    /// <summary>
    ///MyTemplate 的摘要说明
    /// </summary>
    public class MyTemplate : ITemplate
    {
        private DataControlRowType dataControlRowType;

        private string dataField;
        public string DataField
        {
            get { return dataField; }
            set { dataField = value; }
        }

        private string columnName;
        public string ColumnName
        {
            get { return columnName; }
            set { columnName = value; }
        }

        private string controlID;
        public string ControlID
        {
            get { return controlID; }
            set { controlID = value; }
        }

        private bool isGrid;
        public bool IsGrid
        {
            get { return isGrid; }
            set { isGrid = value; }
        }

        public MyTemplate(string columnName)
        {
            dataControlRowType = DataControlRowType.Header;
            this.columnName = columnName;
        }

        public MyTemplate(string controlID, string dataField, bool isGrid)
        {
            dataControlRowType = DataControlRowType.DataRow;
            this.dataField = dataField;
            this.controlID = controlID;
            this.isGrid = isGrid;
        }

        #region ITemplate 成员
        JXSoft.TicketManage.BLL.TicketTypeBLL ticketTypeBLL = new JXSoft.TicketManage.BLL.TicketTypeBLL();
       
        void ITemplate.InstantiateIn(Control container)
        {
            switch (dataControlRowType)
            {
                case DataControlRowType.Header:
                    Literal l = new Literal();
                    l.Text = ColumnName;
                    container.Controls.Add(l);
                    break;
                case DataControlRowType.DataRow:
                    if (!isGrid)
                    {
                        Label lbl = new Label();
                        lbl.ID = ControlID;
                        lbl.DataBinding += new EventHandler(lbl_DataBinding);
                        container.Controls.Add(lbl);
                    }
                    else
                    {
                        Label lbl = new Label();
                        lbl.ID = ControlID;
                        lbl.DataBinding += new EventHandler(lbl_DataBinding);
                        container.Controls.Add(lbl);

                        #region 添加GridView 及内部绑定列
                        GridView gv = new GridView();
                        gv.ID = "GridView2";
                        gv.AutoGenerateColumns = false;

                        BoundField bf;

                        bf = new BoundField();
                        bf.HeaderText = "编号";
                        bf.DataField = "id";
                        gv.Columns.Add(bf);

                        bf = new BoundField();
                        bf.HeaderText = "类型";
                        bf.DataField = "type";
                        gv.Columns.Add(bf);

                        bf = new BoundField();
                        bf.HeaderText = "名称";
                        bf.DataField = "name";
                        gv.Columns.Add(bf); 
 
                        TableRow trow = new TableRow();
                        TableCell cell = new TableCell();
                        cell.ColumnSpan = 3;
                        cell.Controls.Add(gv);
                        trow.Cells.Add(cell);

                        container.Controls.Add(trow);
                        #endregion
                   
                    }
                    break;
                default:
                    break;
            }
        }

        void lbl_DataBinding(object sender, EventArgs e)
        {
            Label lbl = sender as Label;
            GridViewRow gr = lbl.NamingContainer as GridViewRow;
            lbl.Text = DataBinder.Eval(gr.DataItem, DataField).ToString();
        }

        #endregion
    }
    #endregion
 

 也就是说我们可以在后台将所有的模板列动态的添加进GridView1

代码
        TemplateField tf;

        tf = new TemplateField();
        tf.HeaderTemplate = new MyTemplate("编号");
        tf.ItemTemplate = new MyTemplate("lblId", "id", false);
        GridView1.Columns.Add(tf);

        tf = new TemplateField();
        tf.HeaderTemplate = new MyTemplate("姓名");
        tf.ItemTemplate = new MyTemplate("lblName", "name", false);
        GridView1.Columns.Add(tf);

        tf = new TemplateField();
        tf.HeaderTemplate = new MyTemplate("年龄");
        tf.ItemTemplate = new MyTemplate("lblAge", "age", false);
        GridView1.Columns.Add(tf);

        tf = new TemplateField();
        tf.HeaderTemplate = new MyTemplate("");
        tf.ItemTemplate = new MyTemplate("GridView1", "age", true);
        GridView1.Columns.Add(tf);
 

接下来就可以在行绑定事件中找到GridView2并绑定数据了。分页也没问题。

当然也可以顺利导出。导出需要加以下代码:

 

代码
        protected void btnExport_Click(object sender, EventArgs e)
        {
            this.GridView1.AllowPaging = false;
            BindDetailReportToGv();

            Response.Clear();
            Response.AddHeader("content-disposition", "attachment;filename=DetailsLog.xls");
            Response.ContentType = "application/vnd.xls";
            System.IO.StringWriter sw = new System.IO.StringWriter();
            System.Web.UI.HtmlTextWriter htmlWrite = new HtmlTextWriter(sw);
            this.GridView1.RenderControl(htmlWrite);
            Response.Write(sw.ToString());
            Response.End();
            this.GridView1.AllowPaging = true;
        }

        public override void VerifyRenderingInServerForm(Control control)
        {
            // Confirms that an HtmlForm control is rendered for
        }
 

 其实解决这个问题应该还有更好的办法,关键在于2点:

第一个问题是如果一级数据中有动态列,那么分页时的行绑定事件内找不到行里的GridView2,

第二个问题是导出数据时由于采用colspan=“100%”,页面看上去是嵌套了,但是导出为excel后布局就会乱了。

您有更好的办法吗,欢迎交流。
 

热推产品

  • ActiveReport... 强大的.NET报表设计、浏览、打印、转换控件,可以同时用于WindowsForms谀坔攀戀Forms平台下......
  • AnyChart AnyChart使你可以创建出绚丽的交互式的Flash和HTML5的图表和仪表控件。可以用于仪表盘的创......
首页 | 新闻中心 | 产品中心 | 技术文档 | 友情连接 | 关于磐岩 | 技术支持中心 | 联系我们 | 帮助中心 Copyright-2006 ComponentCN.com all rights reserved.重庆磐岩科技有限公司(控件中国网) 版权所有 电话:023 - 67870900 传真:023 - 67870270 产品咨询:sales@componentcn.com 渝ICP备12000264号 法律顾问:元炳律师事务所 重庆市江北区塔坪36号维丰创意绿苑A座28-5 邮编:400020
在线客服
在线客服系统
在线客服
在线客服系统