简体   繁体   中英

ASP.NET Can't add more than 1 label to a div?

Hello I have a simple asp.net webform I'm playing with:

    <div id="in_mess" runat=server >

        <div class="dialog" runat=server> 
            <p class="dialog_interior">Test Message</p>
        </div>

    </div>

    <div id="out_mess" runat=server>

    </div>

</div>

<div id="mess_con" runat=server>

        <form runat=server id="form_con" >
            <p><label>Message</label><input type="text" width="250" id="inp_message"></p> <br>
            <p><label>To</label><input type="text" width="100" id="inp_recepeint"></p> <br>
            <asp:Button ID="ButtonChat" text="Chat" runat=server 
                onclick="ButtonChat_Click" />
        </form>



</div>

In the code behind I've implemented the following simple function for when ButtonChat is clicked:

protected void ButtonChat_Click(object sender, EventArgs e)
{
    this.in_mess.Controls.Add(new Label { Text = "Hello", CssClass = "dialog" });
}

The problem is that I can't get it to add more than one label to the div, the label I added remains but as far as I can see no new ones are added no matter how many times I click.

I've put a breakpoint on the line and it shows the count of the controls collection remains unchanged at 3.

I ran into a similar problem when adding <p> tags via JavaScript which I fixed by stopping the form from reloading the page but I'm not sure if you can apply this to ASP.NET.

You are on the right track with your thinking about the page reloads. In WebForms, the onclick events generate a full postback. The dynamically added controls aren't automatically remembered, so you are only adding 1 more to what the markup page has.

You could remember how many labels you added, and then add them all back again on page load, however I don't really like that solution.

Maybe you can use onclientclick to add the label using Javascript?

<script type="text/javascript">
    function ButtonChat_Click(){
        var label = document.createElement("label");
        label.className = "dialog";
        label.createTextNode("Hello");
        document.getElementById("in_mess").appendChild(label);
    }
 </script>

 <div id="in_mess" runat=server >
    <div class="dialog" runat=server> 
        <p class="dialog_interior">Test Message</p>
    </div>

 </div>

 <div id="out_mess" runat=server>

 </div>

 <div id="mess_con" runat=server>

     <form runat=server id="form_con" >
        <p><label>Message</label><input type="text" width="250" id="inp_message"></p> <br>
        <p><label>To</label><input type="text" width="100" id="inp_recepeint"></p> <br>
        <asp:Button ID="ButtonChat" text="Chat" runat=server onclientclick="ButtonChat_Click" />
     </form>

 </div>

Javascript, is not the only solution here. To persist the state of the page over several postbacks, you have to deal with the sites viewstate. This is also very useful for other things like keeping property values persistent over several postbacks.

Utilizing your ASPX, I would suggest the following codebehind. I don't use Labels as ListItems, because the ViewState objects need to be serializable.

public partial class _default : System.Web.UI.Page
{
    public List<LabelInfo> LabelInfos
    {
        get
        {
            object listOfLabelInfos = ViewState["Labels"];
            return (listOfLabelInfos == null) ? null : (List<LabelInfo>)listOfLabelInfos;
        }
        set
        {
            ViewState["Labels"] = value;
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        // Init the LabelInfo list, if this page load is not a postback.
        if (!IsPostBack)
        {
            LabelInfos = new List<LabelInfo>();
        }
    }

    protected void btnTest_Click(object sender, EventArgs e)
    {
        LabelInfos.Add(new LabelInfo { Text = "TestLabel", CssClass = "TestClass" });

        foreach (LabelInfo l in LabelInfos)
        {
            this.in_mess.Controls.Add(new Label { Text = l.Text, CssClass = l.CssClass });
        }
    }
}

[Serializable]
public class LabelInfo
{
    public string Text = "";
    public string CssClass = "";
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM