动态添加DropDownlists不触发SelectedIndexChanged事件 [英] Dynamically Added DropDownlists Are Not Firing SelectedIndexChanged Event
问题描述
我看到了很多东西关于这个话题,但我不能鳍的解决方案。
我增加了许多下拉列表中选择一个事件,但他们不点火的SelectedIndexChanged EVET。
这里是drplist创code:
I saw lots of thing about this topic but i can't fin a solution. I add many dropdown list with one event but they are not firing SelectedIndexChanged evet. Here is drplist creator code:
foreach (var row in cmdSelectCats.ExecuteReader())
{
var id = row["ProductCategoryID"].ToString();
var dropDownStatus = new DropDownList {ID = "DrpStatus-" + id};
dropDownStatus.Items.Add(new ListItem("Aktif", "1"));
dropDownStatus.Items.Add(new ListItem("Pasif", "2"));
dropDownStatus.AutoPostBack = true;
dropDownStatus.SelectedIndexChanged += Status_SelectedIndexChanged;
var tableCell = new TableCell();
tableCell.Controls.Add(dropDownStatus);
dropDownStatus.SelectedValue = row["ProductCategoryStatusID"].ToString();
tableRow.Cells.Add(tableCell);
TblCatList.Rows.Add(tableRow);
}
和ofcourse我的事件:
And ofcourse my Event:
public void Status_SelectedIndexChanged(object sender, EventArgs e)
{
//DO SOMETHING
}
我想什么?
推荐答案
这是一个常见的问题,它关系到页面生命周期:
This is a common issue and it's related to the page life cycle:
在以下几个问题请看下图:
Take a look at the following questions:
现在的基本步骤来创建动态控件时记住是:
Now the basic steps to remember when creating dynamic controls are:
- 动态控制应在
preINIT
事件被创建时,你是不是有一个母版页的工作,如果你是,那么在<$创建控件C $ C>初始化事件 - 避免将可以在这些事件中每一个职位进行更改的属性,因为在应用视图状态(在事件后)的属性将会被覆盖
- 动态控制必须创建每次页面发布时间,避免这种
如果this.CreatemyDynamicControls()(this.IsPostBack!);
- 当你在
preINIT
或初始化
事件,他们的国家将自动设置创建控件在后事件,这意味着在LoadComplete
事件您的控件将再次抑制自己的状态恢复,甚至当你创建它们在每个岗位,甚至当你没有明确设置其状态。的注意这种行为是不同的,当你正在处理在设计时创建的控件,在这种情况下,在国家已设置的事件是Load事件的 - 应
PageLoadComplete
,否则将不会引发 之前发生事件订阅
- Dynamic controls should be created in the
PreInit
event when you are not working with a master page, if you are, then create the controls in theInit
event - Avoid setting properties that can be changed in each post in these events because when the view state is applied (in a post event) the properties will be overridden
- Dynamic controls must be created every time the page is posted, avoid this
if(!this.IsPostBack) this.CreatemyDynamicControls();
- When you create the controls in the
PreInit
orInit
events, their states will be automatically set in a post event, which means in theLoadComplete
event your controls will contain their state back even when you create them again in each post and even when you did not explicitly set their state. Note this behavior is different when you are dealing with controls created at design time, in that case, the event where the state has been set is the Load event - Event subscription should occur before the
PageLoadComplete
or they will not be raised
考虑从MSDN下面的说明
Consider the following description from MSDN
如果在运行时动态创建的控件或声明中的数据绑定控件模板,他们的活动最初不与其他控件的页面上同步。例如,对于在运行时增加了一个控制,init和负载事件可能晚得多的比以声明方式创建控件相同的事件的页面生命周期的发生。因此,从它们被实例化时,动态添加管制和模板提高他们的事件一前一后,直到它们已经赶上到在此期间它被添加到控制集合的事件。
If controls are created dynamically at run time or declaratively within templates of data-bound controls, their events are initially not synchronized with those of other controls on the page. For example, for a control that is added at run time, the Init and Load events might occur much later in the page life cycle than the same events for controls created declaratively. Therefore, from the time that they are instantiated, dynamically added controls and controls in templates raise their events one after the other until they have caught up to the event during which it was added to the Controls collection.
以上是不那么清楚,我,但我发现以下。以下文本框
的在设计时创建
The above is not so clear to me, but I have found the following. The following TextBox
's are created at design time
protected void Page_PreInit(object sender, EventArgs e)
{
this.txtDesignTextBox1.Text = "From PreInit";
this.txtDesignTextBox1.Text += DateTime.Now.ToString();
}
protected void Page_Init(object sender, EventArgs e)
{
this.txtDesignTextBox2.Text = "From Init";
this.txtDesignTextBox2.Text += DateTime.Now.ToString();
}
protected void Page_Load(object sender, EventArgs e)
{
this.txtDesignTextBox3.Text = "From Load";
this.txtDesignTextBox3.Text += DateTime.Now.ToString();
}
乍一看,你可能会认为,在每一个岗位都与当前日期被更新的文本框,但这种情况并非如此,因为他们在设计时创建他们遵循严格的ASP.Net页面生命周期,这意味着他们的状态是preINIT后重写和Init事件,只有 txtDesignTextBox3
在每一个岗位进行更新,因为它的文本
属性的视图状态的设置后,更新的(在加载
事件)。
At first sight you might think that in every post all the textboxes are updated with the current date, but this is not the case, since they were created at design time they follow strictly the ASP.Net page life-cycle which means, their state is overriden after the PreInit and Init events, only the txtDesignTextBox3
is updated in every post because its Text
property is updated after the view state has been set (in the Load
event).
但随着动态控制的行为是不同的,记得MSDN描述:
But with dynamic controls the behavior is different, remember the MSDN description:
对于在运行时增加了一个控制,init和负载事件可能会在页面生命周期的后期发生
for a control that is added at run time, the Init and Load events might occur much later in the page life cycle
考虑以下几点:
protected void Page_PreInit(object sender, EventArgs e)
{
var textBox = new TextBox { Text = "From PreInit", Width = new Unit("100%") };
textBox.Text += DateTime.Now.ToString();
this.myPlaceHolder.Controls.Add(textBox);
}
protected void Page_Init(object sender, EventArgs e)
{
var textBox = new TextBox { Text = "From Init", Width = new Unit("100%") };
textBox.Text += DateTime.Now.ToString();
this.myPlaceHolder.Controls.Add(textBox);
}
protected void Page_Load(object sender, EventArgs e)
{
var textBox = new TextBox { Text = "From Load", Width = new Unit("100%") };
textBox.Text += DateTime.Now.ToString();
this.myPlaceHolder.Controls.Add(textBox);
}
在这种情况下,控制行为略有不同,在这种情况下,每个岗位,控件是永远不会更新甚至没有在加载创建的控件
事件
In this case, the controls behave slightly different, in this case, in each post, the controls are never updated not even the controls created in the Load
event
原因是被覆盖更晚出现在页面的生命周期,这意味着他们的国家他们的生命周期事件均匀Load事件后
The reason is their life-cycle events occurs much later in the page-life cycle which means their state is overridden even after the Load event
要解决这个问题,你可以使用 LoadComplete
事件,在这个事件中,你可以改变动态控件的状态:
To solve this, you can use the LoadComplete
event, in this event you can change the state of dynamic controls:
protected void Page_LoadComplete(object sender, EventArgs e)
{
var textBox = new TextBox { Text = "From LoadComplete", Width = new Unit("100%") };
textBox.Text += DateTime.Now.ToString();
this.myPlaceHolder.Controls.Add(textBox);
}
在这种情况下,国家将在每一个职位进行更新。
In this case, the state will be updated in each post.
不过,拿在考虑,你应该订阅动态控件的事件,他们不会被提出的 LoadComplete
事件之前或
However, take in consideration that you should subscribe to dynamic controls events, before the LoadComplete
event or they will not be raised.
的 ...我知道我讨厌这种行为,这就是为什么我喜欢MVC 的
至于在设计时创建的控件的快速参考:请注意 LoadViewState
方法被调用的在的 preINIT
和初始化
事件,但加载之前
事件。在加载
事件被认为的稳定的,因为在这种情况下,您可以访问您的控件的视图状态。还要注意, RaisePostBackEvent
方法重新present引起后背部的控制事件,这可能是中,的SelectedIndexChanged
,点击
,等这个事件被处理的 的的加载
事件之后
As a quick reference for controls created at design time: Notice how the LoadViewState
method is called after the PreInit
and Init
events but before the Load
event. The Load
event is considered stable because in this event you can access the view state of your controls. Also notice that the RaisePostBackEvent
method represent the control event that caused the post back, this can be, the SelectedIndexChanged
, Click
, etc this event is handled after the Load
event
有关完整的详细规格阅读的MSDN页面生命周期文档
For a complete detailed specification read the MSDN Page Life-Cycle documentation
这篇关于动态添加DropDownlists不触发SelectedIndexChanged事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!