嵌套 ASP.NET 用户控件为空

Nested ASP.NET user control is null

我正在使用 Visual Studio 2017 和 .NET 4.7.1 开发 ASP.NET 应用程序。我有一个简单的用户控件,名为 ContentStatsViewer.ascx,它显示几个标签。要显示的值通过 public 属性传递。

其他控件(例如 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 属性 setter 上得到一个 NullReferenceException 因为 this.csvMain 是空的。

我不明白为什么这是空的。我已经尝试将它移动到其他页面事件处理程序,例如 Page_LoadCompletePage_PreRender,结果相同。

有什么想法吗?谢谢。

我已经重现了这个问题。

正如我在评论中提到的,Web 用户控件的子控件在 Init() 阶段被实例化和初始化。

您具有以下层次结构:

NumericContentStatsViewer
    ContentStatsViewer

NumericContentStatsViewer控件内部的ContentStatsViewer控件(csvMain变量)在Init阶段被FrameworkInitialize实例化并初始化[=21] =]

当您自己在 Page_Load() 中实例化 NumericContentStatsViewer 用户控件时,只会调用构造函数和控件在 Asp.Net 生命周期的不同阶段处理操作的方法未执行。

但是,如果您使用 LoadControl() 方法加载控件,

the container raises all of the added control's events until it has caught up to the current event.

https://docs.microsoft.com/en-us/dotnet/api/system.web.ui.templatecontrol.loadcontrol?view=netframework-4.8

试试这个:

protected void Page_Load(object sender, EventArgs e)
{
    ...
    var ncsv = LoadControl("NumericContentStatsViewer.ascx") as NumericContentStatsViewer;
    ncsv.Data_Element = rElement;
    ...
}