【问题标题】:Add asp:Button from codebehind从代码隐藏添加 asp:Button
【发布时间】:2012-05-01 12:49:33
【问题描述】:

我正在构建一个代码隐藏。该表是数据库记录的列表(每行一条记录),我需要为每一行添加一个删除按钮。为此,我当然需要为此构建一个具有唯一 ID 的按钮。为此,我想出了以下内容......这是行不通的。关于如何使它工作的任何提示?

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>";

【问题讨论】:

  • 该表是网格视图还是中继器?还是数据列表?
  • “不起作用”是什么意思?
  • 您所做的只是使用您创建的按钮中的 ClientID 字符串创建一个单元格。您实际上并没有以这种方式将按钮添加到页面。
  • 我认为使用网格视图可以轻松完成所有这些工作。检查这个 ASP.NET GridView 控件演示code.msdn.microsoft.com/CSASPNETGridView-5b16ce70
  • @JPHellemons 我怀疑它根本不是一个控件;相反,看起来他完全是自己生成标记并将其发送到页面。这意味着他可能需要了解 GridView 和 Repeater 控件以及 Eval 绑定。

标签: c# asp.net


【解决方案1】:

您的问题是您只将控件的 ClientID 添加到 html 中,而不是将控件添加到页面本身。

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>"));

【讨论】:

  • 好的,听起来很合理。但是如果我做 Controls.Add,它在哪里结束(初学者)?如何将它添加到表格中我最初想要的位置?谢谢
  • 我已经编辑了我的答案,以包括如何添加表格其余部分的示例。这会将您的删除按钮放置在您想要的表格单元格内。
  • 为什么没有中继器控制?还是datalist,还是gridview?
  • @JPHellemons 你是对的。我相信中继器控制将是这种情况下最强大的解决方案(我赞成 GuthMD 的回答)。数据列表或网格视图可能太多了。不知道 Ondrej 的时间限制,我试图给出一个遵循已经使用的模式的答案。当我有完全在代码中的控件时,我有时会使用这种方法。
【解决方案2】:

不要在后面的代码中创建整个表格标记,而是使用 ASP.NET 提供的控件。

例如,将其放在您的 .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>

并将其包含在您的代码隐藏中:

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;
    }
}

【讨论】:

  • 这个答案比在后面的代码中循环并在那里构建 HTML 要好得多。 @skeletank 的公认答案是关注点分离较少。
【解决方案3】:

我能想到的解决您问题的最佳方法是

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>";

这样你就可以得到任何控件的 HTML。 :) 如果您从后面的代码动态构建 HTML,那么尽量不要使用字符串,而是使用 StringBuilder。字符串是不可变的并且有性能损失。

【讨论】:

  • 我认为注入html代码并不比在页面生命周期中添加控件更好。
  • 我从来没有说过它更好。但如果他是从后面的代码制作 HTML,例如一封电子邮件,那么这是一个好方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多