AutoPostBack不能用于自定义控件
问题描述:
我在ASP.net中创建了一个自定义控件,其中包含一个AutoDownBack设置为true的DropDownList。我还为控件附加了一个事件SelectedIndexChanged,但我发现该事件未被触发。正常的asp.net DropDownList与AutoPostBack设置为true将触发事件。我在VS2010中使用.net 3.5版本。AutoPostBack不能用于自定义控件
这里是我的代码: ServerControl1.cs
[ToolboxData("<{0}:ServerControl2 runat=server></{0}:ServerControl2>")]
public class ServerControl1 : WebControl
{
protected DropDownList drplist;
protected TextBox tb;
protected override void RenderContents(HtmlTextWriter output)
{
drplist.RenderControl(output);
tb.RenderControl(output);
}
protected override void CreateChildControls()
{
base.CreateChildControls();
drplist = new DropDownList() { AutoPostBack = true };
drplist.Items.Add("a");
drplist.Items.Add("b");
drplist.Items.Add("c");
drplist.Items.Add("d");
drplist.SelectedIndexChanged += new EventHandler(drplist_SelectedIndexChanged);
tb = new TextBox();
}
void drplist_SelectedIndexChanged(object sender, EventArgs e)
{
tb.Text = "even fired";
}
}
ServerControl1Test:
protected void Page_Load(object sender, EventArgs e)
{
ServerControl1 ServerControl1 = new ServerControl1();
this.Controls.Add(ServerControl1);
}
谁能告诉我我在这里失踪?
答
首先,您需要将自定义控件作为页面树的一部分。在这种情况下,ASP.NET将能够找到它们并包含所有必需的脚本(如果有的话)。您无需覆盖RenderContents
。只需将您的下拉列表以及文本框添加到Controls
集合。
其次,请阅读API reference的CreateChildControls
。页面底部有评论指出:
请勿覆盖
CreateChildControls
!您将遇到一个受伤的世界, 特别是当涉及到订阅子控件事件! 相反,请创建一个名为
CreateCustomChildControls
的私有方法 。 在那里构建控制树。只需 覆盖OnInit
并在那里致电CreateCustomChildControls
从 。
所以你的情况的代码如下所示:
[ToolboxData("<{0}:ServerControl2 runat=server></{0}:ServerControl2>")]
public class ServerControl1 : WebControl
{
protected DropDownList drplist;
protected TextBox tb;
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
CreateCustomChildControls();
}
private void CreateCustomChildControls()
{
drplist = new DropDownList() { AutoPostBack = true };
drplist.Items.Add("a");
drplist.Items.Add("b");
drplist.Items.Add("c");
drplist.Items.Add("d");
drplist.SelectedIndexChanged += new EventHandler(drplist_SelectedIndexChanged);
tb = new TextBox();
base.Controls.Add(drplist);
base.Controls.Add(tb);
}
void drplist_SelectedIndexChanged(object sender, EventArgs e)
{
tb.Text = "even fired";
}
}