[英]Asp.NET custom server control event handler not firing on second postback
我正在开发一个继承CompositeControl类的Asp.NET(.NET 3.5)中的自定义服务器控件。 在我的控制范围内,我重写了CreateChildControls()
方法,以生成html和Asp.NET服务器控件的混合。 添加的一些Asp.NET控件是LinkButton
(每个LinkButton
都将其Command
事件处理程序设置为我控件中的方法)。 我发现的是,第一次点击其中一个LinkButton时,会触发回发并正确触发事件处理程序方法。 在此事件处理程序方法内部,显式调用CreateChildControls()以重新生成控件以响应回发。 然后我发现后续点击LinkButton
的回发无法引发事件处理程序方法。
我假设我在回发时处理控件再生的方式必定是错误的,但是我无法弄清楚要做什么 - 我知道在第一次回发时,CreateChildControls()被调用了两次可能不是很理想,但是因为在引发任何事件之前调用了CreateChildControls,所以我没有看到解决方法。
我的控件类的简化版本如下所示:
public class SearchResults : CompositeControl
{
private int PageIndex = 0;
protected override void CreateChildControls()
{
//do stuff here e.g.
LinkButton prevLink = new LinkButton();
prevLink.Text = "< Prev";
prevLink.CommandArgument = (PageIndex - 1).ToString();
prevLink.Command += new CommandEventHandler(PagerLinkCommand);
this.Controls.Add(prevLink);
}
protected void PagerLinkCommand(object sender, CommandEventArgs e)
{
PageIndex = int.Parse(e.CommandArgument.ToString());
CreateChildControls();
}
}
编辑这里的问题是由于控件在Sitecore站点中使用而我忘记在web.config文件中使用<typesThatShouldNotBeExpanded>
条目注册控件类型。 此条目用于防止服务器控件使其事件被Sitecore搞砸 - 这可能会导致标准服务器控件(如ListView,GridView和Repeater等)出现类似问题。我的web.config已修改,如下所示:
<typesThatShouldNotBeExpanded>
<type>System.Web.UI.WebControls.Repeater</type>
<type>System.Web.UI.WebControls.DataList</type>
<type>System.Web.UI.WebControls.GridView</type>
<type>MyNamespace.MyCustomControl</type> <!-- This is the bit I added -->
</typesThatShouldNotBeExpanded>
根据我的经验,这种问题通常是由于没有为动态生成的控件分配ID。
LinkButton prevLink = new LinkButton();
prevLink.ID = "prevLink";
道歉......这不是一个完整的答案,而是一个对评论来说太长的调试建议:
在浏览器中保存页面的HTML副本,以进行初始加载,回发加载和第二次回发。 然后使用您最喜欢的比较工具比较文件。 消除显而易见的差异,如搜索结果等。这可以帮助您查明控件ID,缺少控件等的任何问题。
成功动态创建控件的两个绝对键是
1)在页面生命周期中的正确时间创建它们
2)在回发时重新创建EXACT SAME控制层次结构(包括ID)
要获取正确的控制树,请覆盖Controls属性并调用EnsureChildControls,并调用EnsureChildControls而不是PagerLinkCommand中的CreateChildControls。
/// <summary>
/// Gets controls.
/// </summary>
public override ControlCollection Controls
{
get
{
EnsureChildControls();
return base.Controls;
}
}
/// <summary>
/// Create child controls.
/// </summary>
protected override void CreateChildControls()
{
this.Controls.Clear();
//do stuff here e.g.
LinkButton prevLink = new LinkButton();
prevLink.Text = "< Prev";
prevLink.CommandArgument = (PageIndex - 1).ToString();
prevLink.Command += new CommandEventHandler(PagerLinkCommand);
this.Controls.Add(prevLink);
}
protected void PagerLinkCommand(object sender, CommandEventArgs e)
{
PageIndex = int.Parse(e.CommandArgument.ToString());
EnsureChildControls();
}
这种行为的原因不是服务器控件本身,而是与Sitecore相关。 为了使Sitecore不干扰服务器控制回发,有必要在web.config文件的typesThatShouldNotBeExpanded
部分下添加一个条目,如下所示。
<typesThatShouldNotBeExpanded>
<type>System.Web.UI.WebControls.Repeater</type>
<type>System.Web.UI.WebControls.DataList</type>
<type>System.Web.UI.WebControls.GridView</type>
<type>MyNamespace.MyCustomControl</type> <!-- This is the bit I added -->
</typesThatShouldNotBeExpanded>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.