主题:GridView动态生成的控件不能触发OnRowCommand事件,且点击控件按钮后,控件的值会消失。

案例,

由于公司需要绑定的数据列顺序是动态生成的,且有的数据列需要绑定Button控件。所以需要动态绑定TemplateField。

问题,不能触发OnRowCommand事件和点击控件按钮后,控件的列值会消失。

不能触发OnRowCommand代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

namespace WebApplication1
{
    public partial class _Default : System.Web.UI.Page
    {
        //protected override void OnInit(EventArgs e)
        //{

        //    TemplateField customField = new TemplateField();

        //    customField.ShowHeader = true;
        //    customField.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "动态添加列");
        //    GridViewTemplate gvt = new GridViewTemplate(DataControlRowType.DataRow, "lbtn", "Name");
        //    customField.ItemTemplate = gvt;
        //    ContactsGridView.Columns.Add(customField);//添加编辑按钮到gridview
        //}

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                TemplateField customField = new TemplateField();

                customField.ShowHeader = true;
                customField.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "动态添加列");
                GridViewTemplate gvt = new GridViewTemplate(DataControlRowType.DataRow, "lbtn", "Name");
                customField.ItemTemplate = gvt;
                ContactsGridView.Columns.Add(customField);//添加编辑按钮到gridview

                DataTable dt = new System.Data.DataTable();
                dt.Columns.Add("data1");
                dt.Columns.Add("ContactID");

                DataRow dr = dt.NewRow();
                dr["data1"] = "test";
                dr["ContactID"] = "ContactID";
                dt.Rows.Add(dr);

                DataRow dr2 = dt.NewRow();
                dr2["data1"] = "test2";
                dr2["ContactID"] = "ContactID";
                dt.Rows.Add(dr2);

                ContactsGridView.DataSource = dt;
                ContactsGridView.DataBind();
            }
        }

       
        public class GridViewTemplate : ITemplate
        {
            public delegate void EventHandler(object sender, EventArgs e);
            public event EventHandler eh;

            private DataControlRowType templateType;

            private string columnName;
            private string controlID;


            public GridViewTemplate(DataControlRowType type, string colname)
            {

                templateType = type;

                columnName = colname;

            }
            public GridViewTemplate(DataControlRowType type, string controlID, string colname)
            {
                templateType = type;
                this.controlID = controlID;
                columnName = colname;
            }


            public void InstantiateIn(System.Web.UI.Control container)
            {
                switch (templateType)
                {
                    case DataControlRowType.Header:
                        LinkButton lc = new LinkButton();
                        lc.Text = columnName;
                        container.Controls.Add(lc);
                        break;
                    case DataControlRowType.DataRow:
                        LinkButton lbtn = new LinkButton();
                        lbtn.ID = "id1";
                        lbtn.Text = "test";
                       // lbtn.ID = this.controlID;
                        //if (eh != null)
                        //{
                        //    lbtn.Click += new System.EventHandler(eh);
                        //}
                       // lbtn.DataBinding += new System.EventHandler(lbtn_DataBinding);

                        container.Controls.Add(lbtn);

                        break;
                    default:
                        break;
                }
            }

        }

        protected void ContactsGridView_OnRowDataBound(Object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType==DataControlRowType.DataRow)
            {
                LinkButton lb = e.Row.FindControl("id1") as LinkButton;
                lb.CommandArgument = "1";
            }

        }

        protected void ContactsGridView_RowCommand(Object sender, GridViewCommandEventArgs e)
        {
            // If multiple buttons are used in a GridView control, use the
            // CommandName property to determine which button was clicked.
            if (e.CommandName == "Add")
            {
                // Convert the row index stored in the CommandArgument
                // property to an Integer.
                int index = Convert.ToInt32(e.CommandArgument);

                // Retrieve the row that contains the button clicked 
                // by the user from the Rows collection.
                GridViewRow row = ContactsGridView.Rows[index];

                // Create a new ListItem object for the contact in the row.     
                ListItem item = new ListItem();
                item.Text = Server.HtmlDecode(row.Cells[2].Text) + " " +
                Server.HtmlDecode(row.Cells[3].Text);
            }
        }
    }
}
View Code

后来把数据绑定从Page.IsPostBack移出,是可以触发OnRowCommand事件。但是点击的时候都要重新做GridView的查询,效率会比较差。

  protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
               
            }

            TemplateField customField = new TemplateField();

            customField.ShowHeader = true;
            customField.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "动态添加列");
            GridViewTemplate gvt = new GridViewTemplate(DataControlRowType.DataRow, "lbtn", "Name");
            customField.ItemTemplate = gvt;
            ContactsGridView.Columns.Add(customField);//添加编辑按钮到gridview

            DataTable dt = new System.Data.DataTable();
            dt.Columns.Add("data1");
            dt.Columns.Add("ContactID");

            DataRow dr = dt.NewRow();
            dr["data1"] = "test";
            dr["ContactID"] = "ContactID";
            dt.Rows.Add(dr);

            DataRow dr2 = dt.NewRow();
            dr2["data1"] = "test2";
            dr2["ContactID"] = "ContactID";
            dt.Rows.Add(dr2);

            ContactsGridView.DataSource = dt;
            ContactsGridView.DataBind();
        }
View Code

最终解决方法,

1.用BoundField替代TemplateField方法,代码如下。

 ButtonField adup = new ButtonField();
adup.ButtonType = ButtonType.Link;
 adup.HeaderText = "广告上架";
 adup.Text = "test";
adup.CommandName = "shangjia";
 ContactsGridView.Columns.Add(adup);//添加编辑按钮到gridview

 

2.重新写OnInit方法。在OnInit上绑定TemplateField,可以触发OnRowCommand事件。

        protected override void OnInit(EventArgs e)
        {

            TemplateField customField = new TemplateField();

            customField.ShowHeader = true;
            customField.HeaderTemplate = new GridViewTemplate(DataControlRowType.Header, "动态添加列");
            GridViewTemplate gvt = new GridViewTemplate(DataControlRowType.DataRow, "lbtn", "Name");
            customField.ItemTemplate = gvt;
            ContactsGridView.Columns.Add(customField);//添加编辑按钮到gridview
        }

2, 

动态绑定控件不能触发的估计原因是:

1)用TemplateField动态绑定的控件不是服务器端控件,不在ViewState记录,所以刷新页面后,这些列的值会消失,OnRowCommand事件自然也不会触发。

2)而用BoundField,会记录ViewState,所以刷新页面后,就会触发事件OnRowCommand。

3)在OnInit上绑定控件,首先会初始化绑定控件和事件(OnRowCommand重新绑定了)。这样OnRowCommand事件也会触发。

 

posted on 2013-06-30 00:24  chinaagan  阅读(4347)  评论(1编辑  收藏  举报