GridView动态添加模板列,并解决数据列PostBack后数据丢失问题!

http://blog.csdn.net/yuanfang8789/archive/2007/08/17/1748554.aspx

近日在做GridView动态加载模板列的问题是,发现微软的GridView功能竟然如此捉襟见肘。本来想一个AddColumn()即可搞定的问题,到现实中却发现,远非想像中的那般美好。。。。。

于是在网上查了相关的示例,发现都只泛泛讲了一下原理,真正可实用的没有发现,所以一狠心,整理了一下这方面的代码,写了一个派生类。在只使用TextBox模板列的情况下还可以满足要求,至少满足我的要求了。各位可以根据需要扩展即可。本人菜鸟一个,不求甚解,只为实现功能,望高人多多指点。

    /// <summary>
    /// GridView动态模板列
    /// </summary>
    /// <example>
    ///     TemplateFieldEx te = new TemplateFieldEx(150, "动态添加列", "idddd", "id", false);
    ///     GridView1.Columns.Add(te);
    /// </example>
    public class TemplateFieldEx : TemplateField
    {
        /// <summary>
        /// 此无参构造必须实现,否则出错
        /// </summary>
        public TemplateFieldEx()
            :base()
        {
        }

        /// <summary>
        /// 构造模板列,具体样式请在GridView中直接设置
        /// </summary>
        /// <param name="nWidth">当前列限定宽度</param>
        /// <param name="strColumnText">标题字符串</param>
        /// <param name="strTxtID">插入的编辑框ID,注意勿重复</param>
        /// <param name="strField">当前弄绑定的字段</param>
        /// <param name="bReadOnly">编辑框是否只读</param>
        public TemplateFieldEx(int nWidth, string strColumnText, string strTxtID, string strField, bool bReadOnly):
            base()
        {
            this.ControlStyle.Width = Unit.Pixel(nWidth);
            this.ItemStyle.Width = Unit.Pixel(nWidth);
            this.ShowHeader = true;

            this.HeaderTemplate = new GridViewItemTemplate(strColumnText);
            this.ItemTemplate = new GridViewItemTemplate(strTxtID, strField, bReadOnly);
        }
    }
    /// <summary>
    /// GridView模板项
    /// </summary>
    public class GridViewItemTemplate : ITemplate
    {
        private DataControlRowType m_type;
        private bool m_bReadOnly;
        private string m_strTxtID;
        private string m_strColumnText;
        private string m_strField;

        /// <summary>
        /// 此无参构造必须实现,否则出错
        /// </summary>
        public GridViewItemTemplate() : base()
        {
        }

        /// <summary>
        /// 构造表头列对象
        /// </summary>
        /// <param name="strColumnText">表头字符串</param>
        public GridViewItemTemplate(string strColumnText)
        {
            m_type = DataControlRowType.Header;
            m_strColumnText = strColumnText;
        }

        /// <summary>
        /// 构造元素行对象
        /// </summary>
        /// <param name="strTxtID">当前TextBox控件ID</param>
        /// <param name="strField">当前TextBox控件绑定的字段</param>
        /// <param name="bReadOnly">TextBox是否只读</param>
        public GridViewItemTemplate(string strTxtID, string strField, bool bReadOnly)
        {
            m_type = DataControlRowType.DataRow;
            m_strTxtID = strTxtID;
            m_strField = strField;
            m_bReadOnly = bReadOnly;
        }
       
        public void InstantiateIn(System.Web.UI.Control container)
        {
            switch (m_type)
            {
                case DataControlRowType.Header:
                    Literal l = new Literal();
                    l.Text = m_strColumnText;
                    container.Controls.Add(l);
                    break;

                case DataControlRowType.DataRow:
                    TextBox tb = new TextBox();
                     tb.ID = m_strTxtID;

                    tb.Width = Unit.Percentage(100);
                    tb.BorderStyle = BorderStyle.None;
                    tb.DataBinding += new EventHandler(TextBox_DataBinding);
                    tb.ReadOnly = m_bReadOnly;
                    container.Controls.Add(tb);
                    break;

                default:
                    break;
            }

        }

        private void TextBox_DataBinding(object sender, EventArgs e)
        {
            TextBox tb = sender as TextBox;
            GridViewRow gvr = tb.NamingContainer as GridViewRow;
            tb.Text = DataBinder.Eval(gvr.DataItem, m_strField).ToString();
        }
    }

示例代码如下:

    protected void Page_Load(object sender, EventArgs e)
    {
        // 注意此处不可放在if(!IsPostBack)中,否则任何一个PostBack命令将会导致此模板列数据丢失,不知何故??
        PerformDataBind();
    }

    private void PerformDataBind()
    {
        // 注意:此处需要删除列,否则重新添加会导致模板列数量增加
        GridView1.Columns.Clear();
        TemplateFieldEx te = new TemplateFieldEx(150, "动态添加列", "t1", "id", false);
        GridView1.Columns.Add(te);
        te = new TemplateFieldEx(150, "text", "t2", "text", true);
        GridView1.Columns.Add(te);

        GridView1.DataSource = CreateDataSource();
        GridView1.DataBind();
    }

    /// <summary>
    /// 构造数据源
    /// </summary>
    /// <returns></returns>
    DataTable  CreateDataSource()
    {
        DataTable dt = new DataTable();
        DataRow dr;
        dt.Columns.Add(new DataColumn("id", typeof(Int32)));
        dt.Columns.Add(new DataColumn("text", typeof(string)));

        for (int i = 0; i < 16; i++)
        {
            dr = dt.NewRow();
            dr[0] = i;
            dr[1] = "列表项目 " + i.ToString();
            dt.Rows.Add(dr);
        }

        return dt;
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        // 读取TextBox控件内容
        TextBox t = GridView1.Rows[0].Cells[0].FindControl("t1") as TextBox;
        // 如果需要,重新绑定之
           PerformDataBind();
    }
界面代码如下:

    <form id="form1" runat="server">
    <div>
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
            <HeaderStyle BackColor="#C0C0FF" />
        </asp:GridView>
        <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" /></div>
    </form>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值