【发布时间】:2023-04-02 21:25:02
【问题描述】:
我正在使用 Visual Studio 2017 和 .NET 4.7.1 开发一个 ASP.NET 应用程序。我有一个简单的用户控件,名为ContentStatsViewer.ascx,它显示了几个标签。要显示的值通过公共属性传递。
NumericContentStatsViewer.ascx 等其他控件包括ContentStatsViewer.ascx 的实例以及其他内容,如下所示:
<uc:ContentStatsViewer runat="server" ID="csvMain"></uc:ContentStatsViewer>
此控件还具有一些属性,这些属性设置为确定要显示的数据。其中一些属性委托给嵌入的ContentStatsViewer.ascx,如下所示:
public Data_Activities.ElementsRow Data_Element
{
get => this.csvMain.Data_Element;
set => this.csvMain.Data_Element = value;
}
最后,我通过动态加载在常规网页上使用我的NumericContentStatsViewer.ascx 控件。例如:
var ncsv = new NumericContentStatsViewer();
paMain.Controls.Add(ncsv);
我在Page_Load 事件处理程序上执行此操作,并且似乎工作正常。但是,一旦我尝试设置一个委托回嵌入式控件的属性,就会出现异常。例如,如果我执行以下操作:
ncsv.Data_Element = rElement;
...我在 Data_Element 属性设置器上收到 NullReferenceException,因为 this.csvMain 为空。
我不明白为什么这是空的。我尝试将其移至其他页面事件处理程序,例如 Page_LoadComplete 或 Page_PreRender,结果相同。
有什么想法吗?谢谢。
【问题讨论】:
-
您在哪个阶段(PreInit、Init、Load,...)添加控件?
paMain.Controls.Add(ncsv); -
因为如果您在加载阶段加载它,则不会为控件调用 PreInit、Init 方法。这就是为什么它没有初始化它的任何孩子。
-
而不是自己实例化它并将其添加到控件集合中,您应该更喜欢使用
LoadControl()方法加载它,该方法将为您处理所需阶段处理程序方法的调用。 -
paMain.Controls.Add(ncsv) 在页面加载期间在转发器的事件处理程序上被调用。但请注意 paMain.Controls.Add(ncsv) 工作正常。不起作用的是后续的属性分配。
-
是的,完全正确。
NumericContentStatsViewer.ascx包含ContentStatsViewer.ascx并且这些(子控件)在 Init() 期间被初始化。当您使用new()实例化控件时,只会调用构造函数。请您尝试两件简单的事情,1. 使用 LoadControl() 加载控件 2. 在 PreInit() 中执行此操作。看看 LoadControl 的第一句话:“当你将控件加载到容器控件中时,容器会引发所有添加的控件的事件,直到它赶上当前事件为止。”
标签: c# asp.net user-controls dynamic-usercontrols