2011-10-05 81 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中,你应该使用该公共属性将数据绑定到中继器。那是对的吗? –