I have couple of user controls which are statically referenced in aspx. We are setting some public properties on the user controls in Page_Preinit event. The page also references a master page
This was working fine so far. Had to do a ui redesign and we implemented nested master pages.
Now, all of a sudden, 开发者_高级运维the user controls are showing up as null. If I change the master page to parent one (instead of child -nested), it works fine.
Appreciate any pointers to this issue.
some sample code: here ucAddress is null
protected void Page_PreInit(object sender, EventArgs e) { ucAddress.City = "Dallas"; }
This blog post describes the problem very well and also offers a solution. I can confirm that the solution works and I'll repeat the relevant parts here:
The problem
We have a user control and initialize its control in the Init
event so that it is ready when the ViewState
is restored (between Init
and Load
).
Once you start using this encapsulation technique, it won’t be long until you want to pass in a parameter that affects the data you load. Before we do, we need to be aware that the
Init
event is fired in reverse order. That is, the child controls have theirInit
event fired before that event is fired at the parent. As such, thePage.Init
event is too late for us to set any properties on the controls.The natural solution is to try and use the
Page.PreInit
event, however when you do you’ll often find that your control references are allnull
. This happens when your page is implemented using a master page, and it relates to how master pages are implemented. The<asp:ContentPlaceHolder />
controls in a master page use theITemplate
interface to build their contents. This content (child controls) is not usually prepared until theInit
event is called, which means the control references are not available. For us, this represents a problem.
The Solution
The fix is remarkably simple; all we need to do is touch the
Master
property on ourPage
and it will cause the controls to become available. If we are using nested master pages, we need to touch each master page in the chain.
The author of the blog post then offers a nice little snippet that you can execute in the PreInit
handler of your Page
that uses a MasterPage
and contains a user control:
protected override void OnPreInit(EventArgs e)
{
// Walk up the master page chain and tickle the getter on each one
MasterPage master = this.Master;
while( master != null ) master = master.Master;
// Access now initialized user control
ucAddress.City = "Dallas";
}
Found the issue. had to initialize child master page before accessing user control.
精彩评论