0

I know about ASP.NET page life cycle but I'm confused. I have code here which creates buttons from database records. After I click on them, they dissapear with no code triggered. :( I know I have to recreate them in Page_Init but I don't know how. Please help! This is my code:

        try
        {
            con.Open();
            SqlDataReader myReader = null;
            SqlCommand myCom = new SqlCommand("select ID,client from tposClient where CardNo='" + cNo + "'", con);

            myReader = myCom.ExecuteReader();

            Panel panel1 = new Panel();
            panel1.Style["text-align"] = "Center";
            panel1.Style["background"] = "blue";
            div_login.Visible = false;

            while (myReader.Read())
            {
                string b = myReader["client"].ToString();
                string id = myReader["ID"].ToString();

                Button btn = new Button();
                btn.Text = b;
                btn.ID = id;
                btn.Style["width"] = "100px";
                btn.Click += new EventHandler(btn_Click);
                panel1.Controls.Add(btn);

                panel1.Controls.Add(new LiteralControl("<br />"));
                form1.Style.Add("display", "block");
                form1.Controls.Add(panel1);
            }
        }
        catch (Exception k)
        {
            Console.WriteLine(k.ToString());
        }
        finally
        {
            cmdselect.Dispose();
            if (con != null)
            {
                con.Close();
            }
        }
Cybermaxs
  • 24,378
  • 8
  • 83
  • 112
Arnes
  • 403
  • 1
  • 5
  • 20
  • You know that you can even use `UserControls` in a web-databound control like GridView or Repeater? Dynamical controls are unnecessary in most cases. – Tim Schmelter Sep 25 '12 at 14:04
  • I'm not sure. You mean that I should read data in grid and make "buttons". What is your solution? – Arnes Sep 25 '12 at 14:11
  • 1
    I would embed these controls in a reusable [`UserControl`](http://asp.net-tutorials.com/user-controls/using/). Then you can add them to a `TemplateField` of a `GridView` or in a [`Repeater`-control](http://msdn.microsoft.com/en-us/library/x8f2zez5.aspx). To get your dynamic code above working, you need to recreate the controls on postbacks with the same id as before. – Tim Schmelter Sep 25 '12 at 14:15
  • 1
    Side note: Use `Parameterized` queries. You're leaving yourself open to [sql injection](http://en.wikipedia.org/wiki/SQL_injection). – Dave Zych Sep 25 '12 at 14:20
  • That's the point, recreating after postback. I'm confused, don't know how :( – Arnes Sep 25 '12 at 14:23
  • You should at least add the panel declaratively to the page. Where is above code located? Do you get an exception, have you used the debugger? I hope that the connection is not static. – Tim Schmelter Sep 25 '12 at 14:45
  • All code is in one file. I'm getting buttons but after I click one of them they dissapear and no code executed. (code is for showing message box as sample, btw. that code is working if I create button on `Page_Load`) – Arnes Sep 26 '12 at 06:44

1 Answers1

1

You should just put the Button inside a ListView control which will repeat for each result you get back. It will be much easier to work with the buttons this way, and you don't have to deal with recreating the controls on each Postback.

Create a ListView with a button inside of it

<asp:ListView ID="lv1" runat="server" OnItemDataBound="lv1_ItemDataBound">
    <ItemTemplate>
        <asp:Button ID="btn1" runat="server" Text="my Text />
    </ItemTemplate>
</asp:ListView>

After you do your data access, create a Dictionary<string, string> to hold the text and id of each button, and you can then use that to bind your ListView.

//Your data access code
Dictionary<string, string> buttonIdsWithText = new Dictionary<string, string>();
while(myReader.Read())
{
    string buttonText = myReader["client"].ToString();
    string buttonId = myReader["ID"].ToString();
    buttonIdsWithText.Add(buttonId, buttonText);
}
lv1.DataSource = buttonIdsWithText;
lv1.DataBind();

Create an ItemDataBound event handler so you can set your button text

public void lv1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
    if (e.Item.ItemType != ListViewItemType.DataItem)
    {
        return;
    }

    KeyValuePair<string, string> idWithText = 
        (KeyValuePair<string, string>)e.Item.DataItem;
    Button myButton = e.Item.FindControl("btn1") as Button;
    myButton.Text = idWithText.Value;
}

If you need to set the button id specifically to the id you get from the database (and you're using .NET 4) you can set the button's ClientIDMode to Static and set the id to the id you want.

Dave Zych
  • 21,581
  • 7
  • 51
  • 66
  • I have problem with last part. `...KeyValuePair idWithText = (KeyValuePair)e.Item.DataItem;...` – Arnes Sep 26 '12 at 06:51
  • What is the issue? I can't help if I don't know what's wrong. You should be able to cast your `DataItem` as a `KeyValuePair` – Dave Zych Sep 26 '12 at 14:33