1

基于某些条件,我在 Page_Init() 中动态创建了一些复选框、下拉列表和文本框。在同一页面中,我有一个在设计时创建的提交按钮(在 aspx 页面中)。以下是部分代码。文本框的可见性由复选框控制。

现在我有两个问题需要解决: (1) ddl.selectedIndex 总是初始化为 0 而不是 -1。但是在事件处理程序 Sumbit_Click() 中,即使我没有选择任何项目,ddl.selectedIndex 也是 0。(2) 即使复选框被选中,在回发期间,文本框也不会显示。有什么办法可以解决吗?

DropDownList ddl = new DropDownList();
ddl.ID = "ddl" + id;
ddl.DataSource = subCallReasonEntityList;
ddl.DataTextField = "myText";
ddl.DataValueField = "id";                          
ddl.DataBind();
ddl.SelectedIndex = -1;
cell.Controls.Add(ddl);

CheckBox cb = new CheckBox();
cb.ID = "cb" + id;
cb.ClientIDMode = ClientIDMode.Static;
cell.Controls.Add(cb);
cell.Controls.Add(new LiteralControl("<br />"));

TextBox tb = new TextBox();
tb.ID = "txt" + id;
tb.ClientIDMode = ClientIDMode.Static;
tb.Attributes.Add("style", "display:none");
cb.Attributes.Add("onclick", "return cbOtherClicked('" + cb.ClientID + "', '" + tb.ClientID + "')");
cell.Controls.Add(tb);

function cbOtherClicked(control1, control2) {
var cbOther = document.getElementById(control1);
var txtOther = document.getElementById(control2);

if (cbOther.checked) {
    txtOther.style.display = "block";
}
else {
    txtOther.style.display = "none";
}
}
4

1 回答 1

2

这里的问题是您的动态控件没有维护 ViewState。

关键:在将控件添加到表单/页面等后修改控件。如果您在将属性添加到表单之前对其进行修改,则添加的值将不会进入 viewState 并且会在回发时丢失。至少把这个作为一个标准。

所以,这样做:

DropDownList ddl = new DropDownList();
// add first this control 
cell.Controls.Add(ddl);
// now set the values
ddl.ID = "ddl" + id;
ddl.DataSource = subCallReasonEntityList;
ddl.DataTextField = "myText";
ddl.DataValueField = "id";                          
ddl.DataBind();
ddl.SelectedIndex = -1;

并确保您始终在每次回发时重新创建所有动态控件。

当我们动态添加任何控件时,一旦添加它们,它就会“追赶”页面生命周期。一旦控件被添加到“控件”集合中,它错过的所有事件都会被触发。

这就引出了一个很重要的结论:你可以在页面生命周期中的任何时候添加动态控件,直到“PreRender”事件发生。即使你在“PreRender”事件中添加了动态控件,一旦将控件添加到“ Controls”集合,“Init”、“LoadViewState”、“LoadPostbackdata”、“Load”和“SaveViewstate”为此控件触发。

于 2013-09-07T02:52:27.177 回答