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