2011-05-13 52 views
0

我在继承CompositeControl类的Asp.NET(.NET 3.5)中开发自定义服务器控件。在我的控制之内,我重写了CreateChildControls()方法来生成html和Asp.NET服务器控件的混合。一些添加的Asp.NET控件是LinkButton s(每个控件都有它们的Command事件处理程序设置为一个方法)。我发现,第一次点击这些LinkBut​​ton中的一个时,会触发一个回传,并正确触发事件处理程序方法。在此事件处理程序方法内部,显式调用CreateChildControls()以响应回发重新生成控件。然后我发现后续点击LinkButton的回发无法启动事件处理程序方法。我认为我处理回发控件再生的方式必须是错误的,但我不知道该怎么办 - 我意识到这一事实,在第一次回发CreateChildControls()被调用两次,这可能不是理想的,但由于CreateChildControls在任何事件引发之前被调用,所以我没有看到解决方法。Asp.NET自定义服务器控件事件处理程序不在第二个回发上触发

我的控制类的简化版本如下:

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> 
+1

基类应为您调用CreateChildControls() - 尝试删除它。 – IrishChieftain 2011-05-13 15:11:29

回答

0

此行为的原因并非归功于服务器控制本身,而是与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> 
0

要获得正确的控制树,请覆盖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(); 
    }   
+0

这似乎并不幸运。 CreateChildControls()现在不会在PagerLinkCommand()后被调用。 – 2011-05-13 15:41:27

+0

不要忘记调用CreateChildControls()中的base.CreateChildControls() – 2011-05-13 16:01:07

1

在我的经验中,这种问题通常是由于没有为动态生成的控件分配ID。

LinkButton prevLink = new LinkButton(); 
prevLink.ID = "prevLink"; 
+0

我试过分配ID属性,但仍然没有喜悦:( – 2011-05-13 15:39:41

+0

您是否已经为CreateChildControls()方法中的所有生成的控件执行了此操作?具体而言, LinkBut​​ton嵌套的控件。 – 2011-05-13 15:51:06

+0

我觉得这篇文章有帮助:http://www.singingeels.com/Articles/Dynamically_Created_Controls_in_ASPNET.aspx – 2011-05-13 16:05:40

1

道歉...这不是一个完整的答案,但调试建议,是一个评论太长:

在浏览器中保存网页的初始负载的HTML副本,载回传,第二次回发。然后使用您最喜爱的比较工具比较这些文件。消除像搜索结果等明显的差异这可以帮助您找出任何问题控件ID,缺少控制等

两个绝对成功的关键动态创建控件
1)期间,在正确的时间创建他们页面生命周期
2)在回发上重建相同的控制层次结构(包括ID)

相关问题