2011-10-05 80 views
5

我有一個表示嵌套層次結構的類(MyClass),所以該類有一個屬性,它是MyClass的集合。 MyClass也有一個標題屬性動態添加用戶控件到中繼器

爲了在網頁上顯示它,我希望創建一個有中繼器的用戶控件。在項目模板中,我將使用文字顯示標題屬性,並在中繼器的ItemCreated事件上創建一個新的usercontrol實例,並將其添加到中繼器中的當前項目中。

我的問題是,當usercontrol中的Page_Load事件觸發時,如果控件是動態添加的,即使我調用EnsureChildControls,repMyClass repeater poroperty也爲null。我在這裏錯過了什麼嗎?如果我創建一箇中繼器並將我的userctonrol放在項目模板中,它可以正常工作。我不能讓這個動態工作?

用戶控制:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MyControl.ascx.cs" Inherits="MyControl" %> 
Items:<br/> 
<asp:Repeater ID="repMyClass" runat="server" EnableViewState="false" 
    OnItemCreated="repMenuItems_ItemCreated"> 
    <HeaderTemplate><ul><HeaderTemplate> 
    <ItemTemplate> 
     <li><%# Eval("Title") %> 
      <div><asp:PlaceHolder ID="SubItemPlaceholder" runat="server" /></div> 
     </li></ItemTemplate> 
    <FooterTemplate></ul></FooterTemplate> 
</asp:Repeater> 

用戶控制代碼:

public partial class MyControl: System.Web.UI.UserControl 
{ 
    public IEnumerable<MyClass> ChildItems { get; set; } 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     this.repMyClass.DataSource = ChildItems; 
     this.repMyClass.DataBind(); 
    } 

    protected void repMenuItems_ItemCreated(object Sender, RepeaterItemEventArgs e) 
    { 
     if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item) 
     { 
      //Get the MyClass instance for this repeater item 
      MyClass mcCurrent = (MyClass)e.Item.DataItem; 

      //If the MyClass instance has child instances 
      if (mcCurrent.Children != null && mcCurrent.Children.Length > 0) 
      { 
       //Add a new user control and set it's property so it can bind 
       PlaceHolder ph = (PlaceHolder)e.Item.FindControl("SubItemPlaceholder"); 

       MyControl ctl = (MyControl)Page.LoadControl(typeof(MyControl),new object[] {}); 

       ctl.ChildItems = mcCurrent.Children; 
       ph.Controls.Add(ctl); 
      } 
     } 
    } 
} 
+0

你可以編輯這個來解釋,也許清理這個。我想也許你在這句話中有一半編輯沒有完成? 「我的問題是,當Page_Load事件首先用於動態添加的控件時,repNyClass repeater poroperty爲null」 – chrismay

回答

0

您可以在需要你想和負載情況下使用它的屬性控制的另一個構造函數,然後再傳遞它在LoadControl()調用中當前爲空的對象數組中。

另一種方法是在屬性的setter中而不是在控件的Load事件中激發邏輯,因爲實際上這裏是真正的負載,並且如果我得到正確的結果,每個控件的請求觸發一次。

另一種方法是不要動態加載它。

您的項目模板中,你可以有這樣的:

<uc:MyControl runat="server 
    ChildItems='<%# ((MyClass) Container.DataItem).Children %>' 
    Visible='<%# ((MyClass) Container.DataItem).Children.Length > 0 %>' 
    /> 

更新

還有一個辦法,從來沒有給過我的子控件的錯誤在用戶控件內中繼器或頁面生命週期,是使用項目數據綁定事件而不是創建的項目。實際上,當我現在考慮它時,你的代碼不應該是因爲e.Item.DataItem還沒有被綁定。

嘗試將事件更改爲ItemDataBound並查看是否有效。

我仍然建議您將控件包含在項目標記中,並控制事件中控件的可見性(現在爲ItemDataBound)。你可以通過e.Item.FindControl("ControlId") as MyControl之類的東西來引用控件(如果沒有在當前項目中找到,將返回null)。

嘗試結合兩種,或至少改變事件的約束,而不是創建的數據,讓我們看看...

+0

問題是,我的用戶控件有它自己的子控件(在這種情況下是中繼器)。在用戶控件的page_load事件中,repeater變量實際上是null。我無法自己設置它,asp.net框架需要。 – Jeremy

+0

理論是你不需要使用負載,而是使用setter。另一個選擇是在答案更新中,可以解決問題。我認爲問題在於使用的事件,這個問題很有可能成爲問題。 – Meligy

3

我爲創建使用嵌套手風琴報告做這個很久以前。

在指數,當你要動態地添加用戶控件實例:

// Declare Placeholder  
PlaceHolder ph = (PlaceHolder)e.Item.FindControl("SubItemPlaceholder") 

// Adding some literal controls to header 
ph.Controls.Add(new LiteralControl("This is the accordion header!!")); 

// Declare new control variable 
crt = new Control(); 

// Load up your User Control 
crt = LoadControl("~/MyControl.ascx"); 

// Check if it has loaded properly 
if (crt != null) 
{ 
    // GET/SET any custom properties of the User Control 
    ((myClass)crt).title = "Welcome"; 

    // Add the new User Control to the placeholder's controls collection 
    ph.Controls.Add(crt); 
} 

注: 用戶控件,您必須添加「類名」在聲明標記

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyControl.ascx.cs" Inherits="myTest" ClassName="myClass" %> 

此外,您希望在動態創建實例時公開任何屬性,您將它們聲明如下:

public string title { get; set; } 

所以,如果你想爲「repMyClass」創建時強制一個值,你可以將它設置爲一個屬性,並指定你想要的任何值爲programmaticaly。

+0

問題是,我的用戶控件有它自己的子控件(在這種情況下是一箇中繼器)。在用戶控件的page_load事件中,repeater變量實際上是null。我無法自己設置它,asp.net框架需要。 – Jeremy

+0

@傑瑞米:當然可以。只需創建一個類型轉發器的屬性。然後你可以訪問它,實例化它,用它做任何你想做的事情。請澄清 - 根據我你應該在UserControl中有一個公共屬性,在UserControl的Page Load中,你應該使用該公共屬性將數據綁定到中繼器。那是對的嗎? –