将用户控件动态添加到页面会使 UC 内的控件变为空
Dynamically adding a usercontrol to a page leaves controls inside the UC to null
我需要将 UserControl 动态添加到页面上的面板。 UserControl 有一个 ID 为 ARepeater 的 Repeater。我在 Page_Init 上加载并添加了 UC。我在 UC 的 Init、Load 和 PreRender 事件中检查了 ARepeater 的值,但 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.LoadControl
的重载不会将 ascx
绑定到代码隐藏,并且所有关联的子控件最终都将为空。
过去,我通过在构建用户控件后添加另一种设置依赖项的方法来解决这个问题,但这不是一个理想的解决方案。
也就是说你没有做错任何事。如果使用 Page.LoadControl("~/path/to/mycontrol.ascx")
,绑定将正常工作,但不会有构造函数注入。
我相信问题在于支持class实际上与前端页面没有关系,除了通过页面指令将其指定为代码隐藏 class。没有什么能阻止多个不同的前端使用相同的 class 作为代码隐藏,因此通过 Type
加载使得确定正确的 ascx
绑定将变得非常困难或完全不可能是。
首先,您无需进入 Page_Init
即可使用动态控件。 Page_Load
就好了。但是为了填充 Repeater,您可以在 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();
我需要将 UserControl 动态添加到页面上的面板。 UserControl 有一个 ID 为 ARepeater 的 Repeater。我在 Page_Init 上加载并添加了 UC。我在 UC 的 Init、Load 和 PreRender 事件中检查了 ARepeater 的值,但 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.LoadControl
的重载不会将 ascx
绑定到代码隐藏,并且所有关联的子控件最终都将为空。
过去,我通过在构建用户控件后添加另一种设置依赖项的方法来解决这个问题,但这不是一个理想的解决方案。
也就是说你没有做错任何事。如果使用 Page.LoadControl("~/path/to/mycontrol.ascx")
,绑定将正常工作,但不会有构造函数注入。
我相信问题在于支持class实际上与前端页面没有关系,除了通过页面指令将其指定为代码隐藏 class。没有什么能阻止多个不同的前端使用相同的 class 作为代码隐藏,因此通过 Type
加载使得确定正确的 ascx
绑定将变得非常困难或完全不可能是。
首先,您无需进入 Page_Init
即可使用动态控件。 Page_Load
就好了。但是为了填充 Repeater,您可以在 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();