简体   繁体   中英

ASP.NET putting dynamic controls on page in reverse messes up events

I have this weird problem when putting textboxes on the page in reverse. The whole event system is messed up. Changing one textbox fires TextChange on all textboxes. I can fix this by putting the controls in a list first and then call add while iterating trough the list in reverse. But i just want to know why this fails. Heres some code (.net 2.0)

public partial class _Default : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        InitFields();
    }

    private void InitFields()
    {
        int nrFields;
        //We have a static textbox called nrElements, this determines the number
        //of fields to initialize
        if (int.TryParse(nrElements.Text, out nrFields))
        {
            //Put all the dynamic fields on the screen in reverse order
            foreach(Control t in GetDynamicFields(nrFields))
            {
                //Calling Controls.Add works fine
                //Calling Controls.AddAt messes up the events
                //Try changing different textboxes
                plhFields.Controls.AddAt(0, t);
            }
        }
    }

    private IEnumerable<Control> GetDynamicFields(int nrFields)
    {
        for (int i = 0; i < nrFields; i++)
        {
            TextBox txtBox = new TextBox();
            txtBox.ID = string.Format("dynTextBox{0}", i.ToString());
            txtBox.AutoPostBack = true;
            txtBox.TextChanged += t_TextChanged;
            yield return txtBox;
        }
    }

    private void t_TextChanged(object sender, EventArgs e)
    {
        TextBox txtBox = sender as TextBox;
        if (txtBox != null)
            txtBox.Text = txtBox.Text + "Changed ";
    }
}

Try calling InitFields() on the Page_PreInit event rather than Page_Load.

Or an alternative would be to override the CreateChildControls() method ( MSDN Article ), if you use CreateChildControls() you'll need to call EnsureChildControls() on the Page_Load method to make sure the CreateChildControls() method has been called before you try to access any controls which have been created within that method.

Always put dynamic controls in OnInit event. Then viewstate serializer/deserializer will work. And you have to add controls on every request, not just in !IsPostBack.

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