I am developing an ASP.NET application using Visual Studio 2017 and .NET 4.7.1. I have a simple user control, named ContentStatsViewer.ascx
, that that displays a couple of labels. The values to display are passed through public properties.
Other controls such as NumericContentStatsViewer.ascx
include an instance of ContentStatsViewer.ascx
along other content, like this:
<uc:ContentStatsViewer runat="server" ID="csvMain"></uc:ContentStatsViewer>
This control also has some properties that are set to establish what data to display. Some of these properties delegate back to those of the embedded ContentStatsViewer.ascx
, like this:
public Data_Activities.ElementsRow Data_Element
{
get => this.csvMain.Data_Element;
set => this.csvMain.Data_Element = value;
}
Finally, I use my NumericContentStatsViewer.ascx
control on regular web pages by dynamically loading it. For example:
var ncsv = new NumericContentStatsViewer();
paMain.Controls.Add(ncsv);
I am doing this on the Page_Load
event handler, and seems to work fine. However, as soon as I try to set a property that delegates back to the embedded control, I get an exception. For example, if I do the following:
ncsv.Data_Element = rElement;
...I get a NullReferenceException on the Data_Element
property setter because this.csvMain
is null.
I don't understand why this is null. I have tried moving it to other page event handlers such as Page_LoadComplete
or Page_PreRender
, with identical results.
Any ideas? Thank you.
I've reproduced the problem.
As already mentioned in my comments, the child controls of a web user control are instantiated and initialized during the Init() phase.
You have the following hierarchy:
The
ContentStatsViewer
control (thecsvMain
variable) inside theNumericContentStatsViewer
control is instantiated byFrameworkInitialize
and initialized during theInit
phaseWhen you instantiate the
NumericContentStatsViewer
user control in Page_Load() yourself, only the constructor is invoked and the control's methods for handling the operations during different stages of Asp.Net life cycle are left unexecuted.But, if you load your control using the
LoadControl()
method,https://learn.microsoft.com/en-us/dotnet/api/system.web.ui.templatecontrol.loadcontrol?view=netframework-4.8
Try this: