2011-05-13 74 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)

相關問題