Jer*_*emy 5 asp.net data-binding user-controls repeater
我有一个表示嵌套层次结构的类(MyClass),因此该类有一个属性,它是MyClass的集合.MyClass还有一个title属性
为了在网页上显示它,我希望创建一个具有转发器的用户控件.在项目模板中,我将使用文字来显示title属性,并且在转发器的ItemCreated事件上,我将创建usercontrol的新实例,并将其添加到转发器中的当前项目中.
我的问题是,当usercontrol中的Page_Load事件触发时,如果控件是动态添加的,则repMyClass转发器poroperty为null,即使我调用EnsureChildControls.我在这里错过了什么吗?如果我创建一个转发器并将我的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>
Run Code Online (Sandbox Code Playgroud)
用户控制代码:
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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在控件中创建另一个构造函数来获取所需的属性并在加载事件中使用它,然后在 LoadControl() 调用中将其传递到当前空的对象数组中。
另一种方法是在属性的 setter 中而不是在控件的 Load 事件中触发逻辑,因为这里本质上是真正的负载,如果我做对了,每个控件的每个请求都会触发一次。
另一种方法是不动态加载它。
在您的项目模板中,您可以有类似的内容:
<uc:MyControl runat="server
ChildItems='<%# ((MyClass) Container.DataItem).Children %>'
Visible='<%# ((MyClass) Container.DataItem).Children.Length > 0 %>'
/>
Run Code Online (Sandbox Code Playgroud)
更新
另一种从未给我在重复器或页面生命周期内的用户控件中的子控件带来错误的方法是使用项目数据绑定事件而不是项目创建事件。
实际上,当我现在考虑时,您的代码不应该,因为 e.Item.DataItem 尚未绑定。
尝试将事件更改为 ItemDataBound 并查看是否有效。
。
我仍然建议您将控件包含在项目标记中,并控制事件中控件的可见性(现在为 ItemDataBound)。您可以通过类似的方式引用该控件e.Item.FindControl("ControlId") as MyControl(如果在当前项目中找不到,则返回 null)。
尝试将两者结合起来,或者至少将事件更改为数据绑定而不是创建,让我们看看......
| 归档时间: |
|
| 查看次数: |
10756 次 |
| 最近记录: |