locked
Problem with dynamic created buttons in GridView RRS feed

  • Question

  • User-218090889 posted

    I have in my GridView some dynamic created buttons inside custom template. When I click on any of the buttons the entire button in the GridView disappears and the page will not fire. I guess all the dynamic created buttons are losing view state on postback.


    Please how do I put my code to have the buttons maintain View state and get fired?

    Below is some of my codes ( item 1 and 2 below are working very well)

    1)      The page load.
    protected void Page_Load(object sender, EventArgs e)

        {

                    if (!Page.IsPostBack)

            {

                if (!object.Equals(Session["UserId"], null))
                 {

                    //**my connection and sql query here;

                    if (dt.Rows.Count > 0)

                    {

                        GridView1.DataSource = dt;

                        GridView1.DataBind();

     

                    }

                }

            }

     

    2)      GridView Rowdatabond
    public void GridViewUserLots_RowDataBound(object sender, GridViewRowEventArgs e)

        {

            if (e.Row.RowType == DataControlRowType.DataRow)

            {

                PlaceHolder ph = (PlaceHolder)e.Row.FindControl("ph1");
                    Button bt1 = new Button();

                    bt1.ID = "GameCall" ;

                    bt1.Text = "Game Call";

                    bt1.CommandName = "GameCall";

                    bt1.EnableViewState = true;

                    ph.Controls.Clear();

                    ph.Controls.Add(bt1);

                                  

                }

     

    3)      GridView RowCommand
        public void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)

        {

              if (e.CommandName == "GameCall")

               {

                    Button bt1 = (Button)e.CommandSource;

                    GridViewRow row = (GridViewRow)bt1.NamingContainer;

                    Label CallNote = (Label)row.FindControl("Label1");

                    TextBox PlayerID = (TextBox)row.FindControl("PlayerId");

                    string PlayerId = PlayerID.Text;

     

                    if (bt1 != null)

                    {

                        string ID1 = null;

                        string ID2 = null;

                        string ID3 = null;

                        string connetionString = null;

                        SqlConnection con;

                        SqlCommand cmdd;

                        string sql = null;

                        SqlDataReader rdr;

     

     

                        connetionString = "Data Source=Myserver;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False";

                        sql = "SELECT (Id) FROM Table_A WHERE (ABS(CAST((BINARY_CHECKSUM(Id, NEWID())) as int))% 100) < 8 ";

     

                        con = new SqlConnection(connetionString);

                        try

                        {

                            con.Open();

                            cmdd = new SqlCommand(sql, con);

                            rdr = cmdd.ExecuteReader();

                           int i = 0;

                           while (rdr.Read())

                          {

                          switch (i)

                          {

                          case 0:

                          ID1 = Convert.ToString(rdr.GetValue(0));

                          break;

                          case 1:

                          ID2 = Convert.ToString(rdr.GetValue(0));

                          break;

                          case 2:

                          ID3 = Convert.ToString(rdr.GetValue(0));

                          break;

                          }

                          i += 1;

                          }

                            rdr.Close();

                            cmdd.Dispose();

     

                        }

                        finally

                        {

                            con.Close();

                        }

     

                        string GameCalls = "INSERT INTO [Table_B] (PlayerId,ScID) VALUES('" + PlayerId + "','" + ID1 + "'),('" + PlayerId + "','" + ID2 + "'),('" + PlayerId + "','" + ID3 + "')";
                        dbClass.ConnectDataBaseToInsert(GameCalls);

                        
    }                    CallNote.Text = "Game Call has been sent";
                        //ph.Controls.Clear();

                        Response.Redirect("~/GamePage.aspx?Id=" + Session["UserId"].ToString());        
                    };
               

     

    Monday, October 17, 2016 6:19 AM

All replies

  • User-1716253493 posted

    temporary remove try-catch or show exception message in catch block

    See, what happen

    Tuesday, October 18, 2016 12:32 AM
  • User-218090889 posted

    I put this code at the catch block, when I ran the app the button disappears, it did not fire and no exception message shown.

         cmdd.Dispose();
                        }
                        catch (SqlException ex)
                        {
                            throw ex;
                        }
                        finally
                        {
                            con.Close();

    Tuesday, October 18, 2016 6:00 AM
  • User1724605321 posted

    Hi Enzyme,

    The problem is happening because the OnRowDataBound event of GridView is NOT called on next postback ,by default viewstate of GridView is set true .When ViewState is on, Gridview stores data from the same and OnRowDataBound event is not called. Also, at this point View state will not be applied for your buttons as they aren't created in page_load. You could try to bind the gridview  in page_load event , Code below is for your reference :

    <asp:GridView ID="GridView1" runat="server" OnRowDataBound="GridViewUserLots_RowDataBound" AutoGenerateColumns="false">
                    <Columns>
                        <asp:BoundField DataField="Id" HeaderText="Id" ItemStyle-Width="50px" InsertVisible="False" ReadOnly="True" SortExpression="Id"
                            ItemStyle-HorizontalAlign="Center" />
                        <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
                        <asp:BoundField DataField="IdCard" HeaderText="IdCard" SortExpression="IdCard" />
                        <asp:BoundField DataField="Address" HeaderText="Address" SortExpression="Address" />
                        <asp:TemplateField HeaderText="temp1">
                            <ItemTemplate >
                                <asp:PlaceHolder ID="ph1" runat="server"></asp:PlaceHolder>
                            </ItemTemplate>
                        </asp:TemplateField>
                    </Columns>
          </asp:GridView> 
    

    Code behind :

            SqlConnection sqlcon;
            string strCon = System.Configuration.ConfigurationManager.ConnectionStrings["SqlConnectionString"].ConnectionString;
            protected void Page_Load(object sender, EventArgs e)
            {
                 bind();            
            }
           
            public void bind()
            {
                string sqlstr = "select * from TB_User";
                sqlcon = new SqlConnection(strCon);
                SqlDataAdapter myda = new SqlDataAdapter(sqlstr, sqlcon);
                DataSet myds = new DataSet();
                sqlcon.Open();
                myda.Fill(myds, "TB_User");
                GridView1.DataSource = myds;
                GridView1.DataKeyNames = new string[] { "id" };
                GridView1.DataBind();
                sqlcon.Close();
            }
            public void GridViewUserLots_RowDataBound(object sender, GridViewRowEventArgs e)
            {
                if (e.Row.RowType == DataControlRowType.DataRow)
                {
                    PlaceHolder ph = (PlaceHolder)e.Row.FindControl("ph1");
                    Button bt1 = new Button();
                    bt1.Text = "Game Call";
                    bt1.CommandName = "GameCall";
                    bt1.EnableViewState = true;
                    ph.Controls.Clear();
                    ph.Controls.Add(bt1);
    
                }
            }
    
    

    Best Regards,

    Nan Yu

    Tuesday, October 18, 2016 8:35 AM
  • User-218090889 posted

    Hello Nan Yu

    I appreciate you contribution, and that of other fellows.

    I tried this you very code you posted, it is working, but I discovered that on one button click it give double entry into the database, why is it so?

    Tuesday, October 18, 2016 12:03 PM
  • User1724605321 posted

    Hi Enzyme,

    I tried this you very code you posted, it is working, but I discovered that on one button click it give double entry into the database, why is it so?

    Please show your code in button click event , and debug your application to check whether you got two same entry .

    Best Regards,

    Nan Yu

    Wednesday, October 19, 2016 1:23 AM
  • User-218090889 posted

    Nan Yu

    below is my code: it give double entry into database on one button click

    1) the mark up:
    <%@ Page Title="GamePage" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true"
        CodeFile="GamePage.aspx.cs" Inherits="GamePage" %>
    <asp:GridView ID="GridView1" runat="server"
        CellPadding="4" EnableModelValidation="True"
        GridLines="None" Height="123px"
        OnRowDataBound="GridView1_RowDataBound"
         OnRowCommand="GridView1_RowCommand"
                        

        style="margin-right: 0px" ForeColor="#333333" AutoGenerateColumns="False"
        Font-Bold="False" Font-Size="Small" Width="522px"
                        OnSelectedIndexChanged="GridView1_SelectedIndexChanged">
                         
        <AlternatingRowStyle BackColor="White" />
        <Columns>
            <asp:TemplateField>
                <ItemTemplate>
                    <asp:Label ID="Label1" runat="server" style="color: #008000"></asp:Label>
                   
                    <br />
                    <span class="auto-style1" style="color: #000066">Lot ID:.</span><asp:TextBox ID="PlayerId" runat="server" style="height: 19px; width: 152px"
                        BorderColor="#3366CC" BorderStyle="Groove"
                        ReadOnly='True'
                        Text='<%# DataBinder.Eval(Container.DataItem,"PlayerId") %>'
                        OnTextChanged="TextBoxPlayerId_TextChanged" Height="19px" Width="152px"></asp:TextBox>
                     sp:PlaceHolder ID="phGame" runat="server"></asp:PlaceHolder>
                    <br />
                                    
                      </ItemTemplate>
            </asp:TemplateField>

    2) page load:
     protected void Page_Load(object sender, EventArgs e)
        {
            bind();
        }

        public void bind()
        {

    if (!object.Equals(Session["UserId"], null))
                 {

                    //**my connection and sql query here;

                    if (dt.Rows.Count > 0)

                    {

                        GridView1.DataSource = dt;

                        GridView1.DataBind();

                     }

                }

    3) GridView Rowdatabond
    public void GridViewUserLots_RowDataBound(object sender, GridViewRowEventArgs e)

        {

            if (e.Row.RowType == DataControlRowType.DataRow)

            {

                PlaceHolder ph = (PlaceHolder)e.Row.FindControl("ph1");
                    Button bt1 = new Button();

                    bt1.ID = "GameCall" ;

                    bt1.Text = "Game Call";

                    bt1.CommandName = "GameCall";

                    bt1.EnableViewState = true;

                    ph.Controls.Clear();

                    ph.Controls.Add(bt1);

                                  

                }

     4) GridView RowCommand
        public void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)

        {

              if (e.CommandName == "GameCall")

               {

                    Button bt1 = (Button)e.CommandSource;

                    GridViewRow row = (GridViewRow)bt1.NamingContainer;

                    Label CallNote = (Label)row.FindControl("Label1");

                    TextBox PlayerID = (TextBox)row.FindControl("PlayerId");

                    string PlayerId = PlayerID.Text;

     

                    if (bt1 != null)

                    {

                        string ID1 = null;

                        string ID2 = null;

                        string ID3 = null;

                        string connetionString = null;

                        SqlConnection con;

                        SqlCommand cmdd;

                        string sql = null;

                        SqlDataReader rdr;

     

     

                        connetionString = "Data Source=Myserver;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False";

                        sql = "SELECT (Id) FROM Table_A WHERE (ABS(CAST((BINARY_CHECKSUM(Id, NEWID())) as int))% 100) < 8 ";

     

                        con = new SqlConnection(connetionString);

                        try

                        {

                            con.Open();

                            cmdd = new SqlCommand(sql, con);

                            rdr = cmdd.ExecuteReader();

                           int i = 0;

                           while (rdr.Read())

                          {

                          switch (i)

                          {

                          case 0:

                          ID1 = Convert.ToString(rdr.GetValue(0));

                          break;

                          case 1:

                          ID2 = Convert.ToString(rdr.GetValue(0));

                          break;

                          case 2:

                          ID3 = Convert.ToString(rdr.GetValue(0));

                          break;

                          }

                          i += 1;

                          }

                            rdr.Close();

                            cmdd.Dispose();

     

                        }

                        finally

                        {

                            con.Close();

                        }

     

                        string GameCalls = "INSERT INTO [Table_B] (PlayerId,ScID) VALUES('" + PlayerId + "','" + ID1 + "'),('" + PlayerId + "','" + ID2 + "'),('" + PlayerId + "','" + ID3 + "')";
                        dbClass.ConnectDataBaseToInsert(GameCalls);

                        
    }                    CallNote.Text = "Game Call has been sent";
                        ph.Controls.Remove(bt1);  //here I am trying to remove the button dynamically, but it doesn't work//

                        Response.Redirect("~/GamePage.aspx?Id=" + Session["UserId"].ToString());        
                    };
              

    Wednesday, October 19, 2016 4:23 AM
  • User1724605321 posted

    Hi Enzyme,

    I tried below code sample base on your code , and it works fine , code below is for your reference (code difference is shown in comment):

    <asp:GridView ID="GridView1" runat="server" CellPadding="4" EnableModelValidation="True" GridLines="None" Height="123px"
                    OnRowDataBound="GridViewUserLots_RowDataBound" OnRowCommand="GridView1_RowCommand" Style="margin-right: 0px"
                    ForeColor="#333333" AutoGenerateColumns="False" Font-Bold="False" Font-Size="Small" Width="522px">
                    <AlternatingRowStyle BackColor="White" />
                    <Columns>
                        <asp:BoundField DataField="Id" HeaderText="Id" ItemStyle-Width="50px" InsertVisible="False" ReadOnly="True" SortExpression="Id"
                            ItemStyle-HorizontalAlign="Center" />
                        <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
                        <asp:BoundField DataField="IdCard" HeaderText="IdCard" SortExpression="IdCard" />
                        <asp:BoundField DataField="Address" HeaderText="Address" SortExpression="Address" />
                        <asp:TemplateField>
                            <ItemTemplate>
                                <asp:Label ID="Label1" runat="server" Style="color: #008000"></asp:Label>
                                <br />
                                <span class="auto-style1" style="color: #000066">Lot ID:.</span><asp:TextBox ID="PlayerId" runat="server" Style="height: 19px; width: 152px"
                                    BorderColor="#3366CC" BorderStyle="Groove" ReadOnly='True' Text='<%# DataBinder.Eval(Container.DataItem,"IdCard") %>'
                                    Height="19px" Width="152px"></asp:TextBox>
                            </ItemTemplate>
                        </asp:TemplateField>
                        <asp:TemplateField HeaderText="temp1">
                            <ItemTemplate>
                                <asp:PlaceHolder ID="ph1" runat="server"></asp:PlaceHolder>
                            </ItemTemplate>
                        </asp:TemplateField>
                    </Columns>
                </asp:GridView>
    

    Code behind :

            public void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
            {
                if (e.CommandName == "GameCall")
                {
                    Button bt1 = (Button)e.CommandSource;
                    GridViewRow row = (GridViewRow)bt1.NamingContainer;
                    Label CallNote = (Label)row.FindControl("Label1");
                    TextBox PlayerID = (TextBox)row.FindControl("PlayerId");
                    string PlayerId = PlayerID.Text;
    
                    if (bt1 != null)
                    {
                        string ID1 = null;
                        string ID2 = null;
                        string ID3 = null;
                        SqlConnection con;
                        SqlCommand cmdd;
                        string sql = null;
                        SqlDataReader rdr;
    
    
                        sql = "SELECT (classCount) FROM TB_Class WHERE UserId=1";
    
                        con = new SqlConnection(strCon);
                        try
                        {
                            con.Open();
                            cmdd = new SqlCommand(sql, con);
                            rdr = cmdd.ExecuteReader();
                            int i = 0;
                            while (rdr.Read())
                            {
                                switch (i)
                                {
                                    case 0:
                                        ID1 = Convert.ToString(rdr.GetValue(0));
                                        break;
                                    case 1:
                                        ID2 = Convert.ToString(rdr.GetValue(0));
                                        break;
                                    case 2:
                                        ID3 = Convert.ToString(rdr.GetValue(0));
                                        break;
                                }
                                i += 1;
                            }
                            rdr.Close();
                            cmdd.Dispose();
    
                        }
                        finally
                        {
                            con.Close();
                        }
    
                        string GameCalls = "INSERT INTO [Table_B] (PlayerId,ScID) VALUES('" + PlayerId + "','" + ID1 + "'),('" + PlayerId + "','" + ID2 + "'),('" + PlayerId + "','" + ID3 + "')";
                        //dbClass.ConnectDataBaseToInsert(GameCalls);
                        //here is different from yours.
                        try
                        {
                            con.Open();
                            cmdd = new SqlCommand(GameCalls, con);
                            cmdd.ExecuteNonQuery();
                        }
                        finally { con.Close(); }
    
                    }
                    CallNote.Text = "Game Call has been sent";
                    PlaceHolder ph = (PlaceHolder)row.FindControl("ph1"); //In your code, I didn’t find the definition of ph.
                    ph.Controls.Remove(bt1);  
    
                    //Response.Redirect("~/GamePage.aspx?Id=" + Session["UserId"].ToString());
                }
            }
    

    In addition , i found your Rowdatabond event is "GridViewUserLots_RowDataBound" , is that a different gridview ? I notice you bind "GridView1_RowDataBound" event to your GridView1.

    Best Regards,

    Nan Yu

    Wednesday, October 19, 2016 6:38 AM
  • User-218090889 posted

    Hello Nan yu

    Thank you very very much, the code is now working -inserting single value on single button click, the only thing that is not working yet is how to remove the button (bt1) and CallNote is not displaying in Label1, I think my setup is not finding the controls, how do I go about that?

    Thursday, October 20, 2016 4:57 AM
  • User1724605321 posted

    Hi Enzyme ,

    the only thing that is not working yet is how to remove the button (bt1) and CallNote is not displaying in Label

    Please explain more about your requirement , i notice you have removed the button :

       ph.Controls.Remove(bt1);  

    And show the success message to user .

    Best Regards,

    Nan Yu

    Thursday, October 20, 2016 5:58 AM