我需要在页面上的Panel中动态添加一个UserControl。UserControl有一个ID为ARepeater的中继器。我在Page_Init上加载并添加UC。我在UC的Init、Load和PreRender事件中检查了ARepater的值,但ARepeater始终为null。
protected Page_Init(object sender, EventArgs e)
{
var list = (NameList)Page.LoadControl(typeof(NameList), new object[1] { (int)Type });
Panel1.Controls.Add(list);
}
NameList.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="NameList.ascx.cs" Inherits="MyCompant.Controls.BannersList" %>
<asp:Repeater ID="ARepeater" runat="server">
<ItemTemplate>
</ItemTemplate>
</asp:Repeater>
我做错了什么?
首先,您不需要在Page_Init
中就可以使用动态控件。Page_Load
很好。但为了填充中继器,您可以在UserControl 中创建一个属性
public partial class WebUserControl1 : System.Web.UI.UserControl
{
public Repeater _ARepeater
{
get
{
return ARepeater;
}
set
{
ARepeater = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
然后,您可以使用UserControl从页面访问它。
protected void Page_Load(object sender, EventArgs e)
{
var list = (WebUserControl1)LoadControl("~/WebUserControl1.ascx");
list.ID = "MyUserControl";
Panel1.Controls.Add(list);
list._ARepeater.DataSource = source;
list._ARepeater.DataBind();
}
或者使用FindControl
var _ARepeater = (Repeater)Panel1.FindControl("MyUserControl").FindControl("ARepeater");
_ARepeater.DataSource = dt;
_ARepeater.DataBind();
您可能不喜欢这个答案,但允许指定控件类型和添加构造函数参数的Page.LoadControl
重载不会将ascx
绑定到后面的代码,并且所有关联的子控件最终都将为null。
过去,我曾通过在构建用户控件后添加另一种设置依赖关系的方法来解决这个问题,但这不是一个理想的解决方案。
也就是说你没有做错什么。如果使用Page.LoadControl("~/path/to/mycontrol.ascx")
,绑定将正常工作,但不会有构造函数注入。
我认为问题在于后台类实际上与前端页没有关系,除非通过将其指定为代码隐藏类的page指令。没有什么能阻止多个不同的前端使用与其代码隐藏相同的类,因此通过Type
加载会使确定要绑定的正确ascx
变得非常困难或完全不可能