Dynamically added ListBox's EventHandler is not firing on ASP.Net
First of all, Im sorry if my question has possible duplicate, but I searched too much, and I cant find the solution. The scenerio is I have a UserControl. This user control will create dynamically ListBoxes if the given List's count > 0. The controls are adding dynamically, there is no problem with adding them, but the event handler is not adding. If I select an item in first listBox, the secondListBox will be added dynamically, and items will add dynamically too. First listBox appears, but the selectedIndexChanged event handler doesn't work. What can be the problem with my code?
EDIT: I tried to add
li.Attributes.Add("onselectedindexchanged","selectedIndexChanged");
or
li.AutoPostBack = true;
but still not firing...
private List<string> myList = new List<string>() { "Serkan", "Kadir" };
private List<string> mySecondList = new List<string>() { "Istanbul", "Ankara" };
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (myList.Count >开发者_如何学编程 0)
{
ListBox li = new ListBox();
li.ID = Guid.NewGuid().ToString();
li.SelectedIndexChanged += new EventHandler(this.selectedIndexChanged);
foreach (string item in myList)
{
li.Items.Add(item);
}
this.Controls.Add(li);
}
}
}
private void selectedIndexChanged(object sender, EventArgs e)
{
ListBox li2 = new ListBox();
li2.ID = Guid.NewGuid().ToString();
foreach (string item in mySecondList)
{
li2.Items.Add(item);
}
this.Controls.Add(li2);
}
li.Attributes.Add("onselectedindexchanged","selectedIndexChanged");
Adds a client-side HTML attribute. The selectedIndexChanged method you've shown here is a server side method. You either need to add an auto-post-back to your control, and a server-side event handler to the control to make it call your C# function on the server, or make a client-side JavaScript function to handle the client-side event.
edit---
When the page is posted back to the server, the control ceases to exist. The Page is a new isntance, which hasn't had the listbox added to its controls collection. The event IS being called when auto-postback is true, but the control doesn't exist in the server's Page object, and if you remove the If Page.IsPostBack block, the control is re-created, and so the control is not the one whose event was raised, and that control still doesn't exist.
Whats the actual aim of this control? Is it just to provide a master-details thing?
edit 2---
Created solution for you that works:
Page:
<asp:ListBox ID="ListBox1" runat="server" AutoPostBack="true" Visible="false" OnSelectedIndexChanged="ListBox1_SelectedIndexChanged"></asp:ListBox>
<br />
<asp:ListBox ID="ListBox2" runat="server" Visible="false"></asp:ListBox>
Codebehind:
private List<string> myList = new List<string> {
"Serkan",
"Kadir"
};
private List<string> mySecondList = new List<string> {
"Istanbul",
"Ankara"
};
protected void Page_Load(object sender, System.EventArgs e)
{
if (!Page.IsPostBack) {
if (myList.Count > 0) {
ListBox1.DataSource = myList;
ListBox1.DataBind();
ListBox1.Visible = true;
}
}
}
protected void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
ListBox2.DataSource = mySecondList;
ListBox2.DataBind();
ListBox2.Visible = true;
}
1-dynamically add controls must be loaded in the page_init event not in page_load 2-checked listboxes do not work with .attributes.add("selectedindexchanged","...") becuase the check box list is an asp.net control but it renders in html as regular input
The reason your events aren't happening is because you are misunderstanding the ASP.Net page lifecycle. When you request a page, ASP.Net creates a new instance of the corresponding page class. This instance knows nothing about any other instances that have been created in the past. It uses the instance of the Page class to generate a bunch of HTML, which it sends back to the browser as a response. That instance of the Page class on the server is then destroyed, along with its state.
When a page posts back, ASP.Net reads through using the viewstate, ids etc and maps the HTML elements posted back to it to the server controls in your newly created Page instance. The elements you added to the Controls collection of the previous instance don't exist in this new instance, and so ASP.Net cannot recognise them, or fire events on them.
Here is an article that demonstrates the kind of thing I think you are trying to achieve, albeit with GridViews, it uses a similar approach to the solution I previously posted.
http://www.codeproject.com/KB/aspnet/MultiNestMDGridview.aspx
Perhaps you could explain exactly what the end goal is, because there might be a better solution? I fully accept that the limitation of both the approach I posted earlier and the solution in that link is that there are a finite number of levels of detail available, which may or may not be a problem depending on what you're actually trying to do.
Edit--
If you change to the Page_Init event as @Microgen suggests, remove the if (!Page.IsPostBack), set AutoPostBack=true, and use a non-volatile ID for your dynamically added control, this will call the server side event and render the 2nd listbox. It won't work with Guid.New() because the Controls collection on the newly created Page won't contain anything with matching ID so the event handler won't get hooked up. This would answer the question as originally posted. However, your 2nd listbox won't fire events unless you create it and add it to Page.Controls in Page_Init in the same way and so on for the 3rd etc, all for the reason described above.
Folks, my code is working good. I just tried this in a diff visual studio today, and everything worked fine. @RichardW1001 and @Microgen thank you for your interest and posts.
精彩评论