0

我正在使用 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_LoadCompleteor Page_PreRender,结果相同。

有任何想法吗?谢谢你。

4

1 回答 1

1

我已经重现了这个问题。

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

您具有以下层次结构:

NumericContentStatsViewer
    ContentStatsViewer

控件内部的ContentStatsViewer控件(csvMain变量)由阶段NumericContentStatsViewer实例化FrameworkInitialize和初始化Init

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

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

容器引发所有添加的控件的事件,直到它赶上当前事件。

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;
    ...
}
于 2020-03-24T00:47:05.830 回答