Handling events for dynamically generated .NET use

2019-08-11 18:17发布

问题:

I am working on a page that accepts scanned input into a textbox. Once input is entered into the textbox, a user control that contains additional fields for the input item is dynamically generated via autopostback. The user control also contains a link button that is intended to delete the item (itself). Clicking this button generates a "delete" event that is supposed to bubble up to the parent.

Unfortunately this does not seem to happen - the deletion handling code is never reached. My understanding is that it is because the controls have not been generated yet at page load, so the event handlers have not been created yet. But since I don't know what controls need to be generated at page load (since the user input hasn't been processed yet), I can't move the code to generate the user controls to PageLoad.

How should this be handled? Am I going about this the wrong way? Most of my relevant code is below.

Thanks for any help!

page.aspx:

Enter SKU (tab to enter): 
<asp:TextBox ID="EntryTextBox" CssClass="textbox" AutoPostBack="true" OnTextChanged="newItem" runat="server"></asp:TextBox>
<asp:Panel ID="itempanel" runat="server">
</asp:Panel>

page.aspx.cs:

protected void newItem(object sender, EventArgs e)
{
    // we need to store item entries in ViewState so they comeback on postback;
    // they can't be stored in the controls themselves as the controls will
    // disappear
    ViewState["skus"] += "\t" + EntryTextBox.Text;
    ViewState["descs"] += "\t" + itemLookup(EntryTextBox.Text);
    // ...more item descriptors...
    updateItemPanel();
}

protected void updateItemPanel()
{
    // generate a control for each item entered in ViewState
    itempanel.Controls.Clear();
    List<string> skus = new List<string>(ViewState["items"].ToString().Substring(1).Split('\t'));
    List<string> descs = new List<string>(ViewState["descs"].ToString().Substring(1).Split('\t'));
    // ...more item descriptors...
    int i = 0;
    foreach (string sku in skus)
        {
            item newitemctrl = (item)Page.LoadControl("~/item.ascx");
            newitemctrl.line = (i + 1).ToString();
            newitemctrl.sku = skus[i];
            newitemctrl.description = descs[i];
            // ...more item descriptors...
            newitemctrl.deleteLinkClicked += new EventHandler(deleteClicked);
            itempanel.Controls.Add(newitemctrl);
            i++;
        }
    }

    protected void deleteClicked(object sender, EventArgs e)
    {
        List<string> skus = new List<string>(ViewState["skus"].ToString().Substring(1).Split('\t'));
        List<string> descs = new List<string>(ViewState["descs"].ToString().Substring(1).Split('\t'));
        // ...more item descriptors...
        item olditemctrl = (item)sender;
        skus.RemoveAt(Convert.ToInt32(olditemctrl.number) - 1);
        descs.RemoveAt(Convert.ToInt32(olditemctrl.number) - 1);
        ViewState["skus"] = skus.ToString();
        ViewState["descs"] = descs.ToString();
        updateItemPanel();
    }

item.ascx:

<asp:LinkButton ID="DeleteLinkButton" runat="server" onclick="DeleteLinkButton_Click">Delete</asp:LinkButton>

item.ascx.cs:

    public event EventHandler deleteLinkClicked;

    protected void DeleteLinkButton_Click(object sender, EventArgs e)
    {
        if (this.deleteLinkClicked != null)
        {
            this.deleteLinkClicked(new object(), new EventArgs());
        }
    }

回答1:

You can dispatch a postback event in javascript by adding this as onclick event:

__doPostBack("<%= button.ClientID %>", "");

DoPostBack has two arguments, the first is the ID, the second is the event name. I used this solution successfully.

You'll find more information here.

Note: This itself does not fire the event automatically, but you can see what you want to happen in the Load Event of your page. You can get the arguments like this: : Request.Form["__EVENTTARGET"] You have full access to the form data, so you can also get the values from the dynamically created controls