Reputation: 15335
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.
Upvotes: 1
Views: 631
Reputation: 7187
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:
NumericContentStatsViewer
ContentStatsViewer
The ContentStatsViewer
control (the csvMain
variable) inside the NumericContentStatsViewer
control is instantiated byFrameworkInitialize
and initialized during the Init
phase
When 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,
the container raises all of the added control's events until it has caught up to the current event.
Try this:
protected void Page_Load(object sender, EventArgs e)
{
...
var ncsv = LoadControl("NumericContentStatsViewer.ascx") as NumericContentStatsViewer;
ncsv.Data_Element = rElement;
...
}
Upvotes: 1