Ondrej
Ondrej

Reputation: 1660

Add asp:Button from codebehind

I'm building a in codebehind. The table is a listing of a database records (one record per row) and I neeed to add a delete button for each row. To do that, I of course need to build a button with a unique ID for that. To do that, I came up with the following ... which doesn't work. Any tips on how to get this working?

Button deleteButton = new Button();
deleteButton.ID = "deleteStudentWithID" + singleStudent.ID.ToString();
deleteButton.Text = "X";

string row = "<tr>";
row += "<td class=\"style5\">"+deleteButton.ClientID +"</td>";
row += "</tr>";

Upvotes: 0

Views: 8466

Answers (3)

skeletank
skeletank

Reputation: 2888

Your problem is that you're adding only the ClientID of your control to the html and not adding the control to the page itself.

Controls.Add(new LiteralControl("<table>"));

foreach(var singleStudent in students)
{
    Controls.Add(new LiteralControl("<tr>"));

    //Code to add other columns

    Button deleteButton = new Button();
    deleteButton.ID = "deleteStudentWithID" + singleStudent.ID.ToString();
    deleteButton.Text = "X";

    Controls.Add(new LiteralControl("<td class=\"style5\">"));
    Controls.Add(deleteButton);
    Controls.Add(new LiteralControl("</td></tr>");
}

Controls.Add(new LiteralControl("</table>"));

Upvotes: 5

Mike Guthrie
Mike Guthrie

Reputation: 4059

Instead of creating the entire table markup in your code behind, use the controls made available by ASP.NET.

For an example, place this in your .aspx:

<table>
    <asp:Repeater runat="server" ID="MyRepeater1">
        <ItemTemplate>
            <tr>
                <td><%# Eval("StudentName")%></td>
                <td>... other student object bindings ...</td>
                <td>
                    <asp:Button runat="server" ID="MyDeleteButton"
                            CommandArgument='<%# Eval("ID")%>'
                            CommandName="Delete"
                            OnCommand="MyDeleteButton_Command"
                            Text="X" />
                </td>
            </tr>
        </ItemTemplate>
    </asp:Repeater>
</table>

And include this in your code-behind:

protected void Page_Load(object sender, EventArgs e)
{
    MyRepeater1.DataSource = new MyStudent[]
        {
            new MyStudent()
                {
                    ID = 1,
                    StudentName = "Student 1"
                },
            new MyStudent()
                {
                    ID = 2,
                    StudentName = "Student 2"
                }
        };
    MyRepeater1.DataBind();
}

protected void MyDeleteButton_Command(object sender, CommandEventArgs e)
{
    switch (e.CommandName)
    {
        case "Delete":
            // stuff for deleting by e.CommandArgument
            break;
    }
}

Upvotes: 3

Kamran Pervaiz
Kamran Pervaiz

Reputation: 1931

The best Solution to Your problem i can think of is

Button deleteButton = new Button();
deleteButton.ID = "deleteStudentWithID" + singleStudent.ID.ToString();
deleteButton.Text = "X";

StringBuilder sb = new StringBuilder();
StringWriter writer = new StringWriter(sb);
HtmlTextWriter htmlWriter = new HtmlTextWriter(writer);
deletedButton.RenderControl(htmlWriter);

string row = "<tr>";
row += "<td class=\"style5\">"+sb.toString(); +"</td>";
row += "</tr>";

This way you can get any control's HTML. :) If you are building dynamically HTML from code behind then try not to use string rather StringBuilder. strings are immutable and has performance penalty.

Upvotes: 1

Related Questions