Setting the value of a Master page's control's property using a property of the Master page

  • Thread starter Thread starter Nathan Sokalski
  • Start date Start date
N

Nathan Sokalski

I have a Master page that contains a custom property, defined as follows:


Public Property SelectedNavigationID() As String
Get
Return Me.leftnavNavigation.SelectedNavigationID
End Get
Set(ByVal value As String)
Me.leftnavNavigation.SelectedNavigationID = value
End Set
End Property


As you can see, this property is used to set the value of a property of one
of the Master page's Controls. I set the property from the Content page as
follows:


Private Sub Page_PreInit(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.PreInit
Me.Master.SelectedNavigationID = "menuConditionalValidator"
End Sub


The problem occurs in the Set method of the property defined in the Master
page; it tells me that Me.leftnavNavigation has a value of Nothing, which
obviously prevents me from setting the property. I know that I am missing
something simple, because this is almost exactly the same as a previous
version of the site I am recreating, which works perfectly. What could be
causing the problem? Any help would be appreciated. Thanks.
 
I have a Master page that contains a custom property, defined as follows:

Public Property SelectedNavigationID() As String
        Get
                Return Me.leftnavNavigation.SelectedNavigationID
        End Get
        Set(ByVal value As String)
                Me.leftnavNavigation.SelectedNavigationID= value
        End Set
End Property

As you can see, this property is used to set the value of a property of one
of the Master page's Controls. I set the property from the Content page as
follows:

Private Sub Page_PreInit(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.PreInit
        Me.Master.SelectedNavigationID = "menuConditionalValidator"
End Sub

The problem occurs in the Set method of the property defined in the Master
page; it tells me that Me.leftnavNavigation has a value of Nothing, which
obviously prevents me from setting the property. I know that I am missing
something simple, because this is almost exactly the same as a previous
version of the site I am recreating, which works perfectly. What could be
causing the problem? Any help would be appreciated. Thanks.

Try to move the contentpage's code to Page_Load
 
That would not work, because properties of Controls in the Master page must
be set in the PreInit event.
 
I tried that by changing my code from:

Public Property SelectedNavigationID() As String
Get
Return Me.leftnavNavigation.SelectedNavigationID
End Get
Set(ByVal value As String)
Me.leftnavNavigation.SelectedNavigationID = value
End Set
End Property

To:

Public Property SelectedNavigationID() As String
Get
Me.EnsureChildControls()
Return Me.leftnavNavigation.SelectedNavigationID
End Get
Set(ByVal value As String)
Me.EnsureChildControls()
System.Diagnostics.Debug.WriteLine(IsNothing(Me.leftnavNavigation))
Me.leftnavNavigation.SelectedNavigationID = value
End Set
End Property

Not only does the Debug.WriteLine output the value True, but I still get the
same error saying "Object reference not set to an instance of an object.".
Unless I used the EnsureChildControls() method incorrectly here, it
unfortunately did not solve the problem. Any other ideas? Thanks.
 
Nathan,

It looks like now the problem is in eftnavNavigation control (or its
SelectedNavigationID) property.
Try to put a breakpoint on the setter and see whether you can read a value
from the SelectedNavigationID property - then you might be able to set it.

I had similar problem trying to access Master page controls from the page on
PreInit event, when not all child controls (including Master page control)
are initialised. Unfortunately, I do not have the code handy - I will post it
(if I can find it) in the next 8-10 hours.
 
Thank you for your response, I look forward to seeing your code (hopefully
it will help me solve the problem). The line that the error actually occurs
on if I debug is:

Private Sub Page_PreInit(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.PreInit
Me.Master.SelectedNavigationID = "menuConditionalValidator"
End Sub

which is in the Content Page. However, I originally tried placing a
breakpoint on this line to see whether Me.Master was Nothing or not, but it
was perfectly fine, so I then moved the breakpoint to the Set method of the
SelectedNavigationID property in:

Public Property SelectedNavigationID() As String
Get
Return Me.leftnavNavigation.SelectedNavigationID
End Get
Set(ByVal value As String)
Me.leftnavNavigation.SelectedNavigationID = value
End Set
End Property

where I found out that the object that was actually Nothing was
Me.leftnavNavigation. I doubt that the problem is in leftnavNavigation
(although who knows at this point), since it didn't give me any problems in
the project before (but neither did anything else) and I haven't changed
anything, not to mention that it is Nothing at this point, so the only place
the problem could be is in initialization, and I'm guessing I would get some
other error if that was the problem (but I could be wrong). Anyway, I look
forward to seeing your code, and if you think seeing any of my code will
help, just let me know (I just don't want to sent huge amounts of code that
won't help anybody, but I am willing to share any code I write with anybody
who is interested). Thank you again for all your effort, it's good to know
there are people that really care about helping.
 
Nathan Sokalski said:
Thank you for your response, I look forward to seeing your code (hopefully
it will help me solve the problem). The line that the error actually
occurs

I think your problem is trying to do stuff in preinit.
The master page and content are only merged together after the content
page's preinit event.
You cannot do things in a content page's preinit to the master, it ain't
there.

My advice would be to find a way to make your master page happy with being
manipulated in the content page's page_load event.
Maybe look into mastertype as well.
 
That is not true, when I did a debug, I added a Debug.WriteLine as follows:

Private Sub Page_PreInit(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.PreInit
System.Diagnostics.Debug.WriteLine(IsNothing(Me.Master))
Me.Master.SelectedNavigationID = "menuConditionalValidator"
End Sub

This output the value False, which means that Me.Master is not Nothing at
this point.
 
Nathan Sokalski said:
That is not true, when I did a debug, I added a Debug.WriteLine as
follows:

Private Sub Page_PreInit(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.PreInit
System.Diagnostics.Debug.WriteLine(IsNothing(Me.Master))
Me.Master.SelectedNavigationID = "menuConditionalValidator"
End Sub

This output the value False, which means that Me.Master is not Nothing at
this point.

It's a placeholder.
The child controls aren't merged.
 
OK, but that's not the same as being Nothing. If the Master's child controls
aren't merged (I don't cared if they're merged yet), are they created (has
the Master called it's CreateChildControls() method yet?) yet? All I need is
for them to be created, I don't need them to have been initialized or
anything, I just need to be able to set a property that the control will use
when it is initialized and rendered.
 
Nathan Sokalski said:
OK, but that's not the same as being Nothing. If the Master's child
controls aren't merged (I don't cared if they're merged yet), are they
created (has the Master called it's CreateChildControls() method yet?)
yet? All I need is for them to be created, I don't need them to have been
initialized or anything, I just need to be able to set a property that the
control will use when it is initialized and rendered.

In the content page's preinit, there's ONLY a placeholder for the master
page.

The content page's events fire first.
The master page is a child of the content page..

You could prove this to yourself easy.
Turn page trace on.
Add page events to both master and content.
Stick a trace.warn in each that says which they are.
Run your page.

The events do not fire in the order you think they do.
 
Nathan,

I'm sorry I forgot to lookup the code for you - when I got back home, I got
carried away with family stuff.

From memory, to initiate MasterPage child control, I had to call on its
Master property - this caused the whole control tree to load. Something like:
If Me.Master.Master Is Nothing Then
Me.Master.SelectedNavigationID = value
End If

Though it looks like a hack, but it does the job (if I remember correctly) -
give it a shot. If you have a hierarchy of Master pages, you might need to do
even more levels, something like:
If Me.Master Is Nothing OrElse Me.Master.Master Is Nothing OrElse ...

I use PreInit event to populate data controls without adding the data into
ViewState - what is your reason?
 
Well, I finally tried it with the code in Init or Load. When the code is in
Init or Load, the original request works fine, but when I do a postback it
gives me the same problem I received on the original request when it was in
PreInit. When am I allowed to set properties of the Master page's controls
when doing a postback? Thanks.
 
Unfortunately, that code isn't helping. When I tried changing my PreInit to:

Private Sub Page_PreInit(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.PreInit
If Me.Master.Master Is Nothing Then Me.Master.SelectedNavigationID =
"menuConditionalValidator"
End Sub

It gave me the same error I was getting before, since Me.Master.Master Is
Nothing evaluates to True.

I am using PreInit to set a property of a UserControl I created for the
navigation on my site. If this property is not set, the navigation hierarchy
will be collapsed and not have the current page highlighted. If you go to my
website, you can see this UserControl on the left side of all the pages (my
live site is still working, because I haven't tried to update it since I
started having this problem when debugging it at home).
 
Nathan Sokalski said:
Well, I finally tried it with the code in Init or Load. When the code is
in Init or Load, the original request works fine, but when I do a postback
it gives me the same problem I received on the original request when it
was in PreInit. When am I allowed to set properties of the Master page's
controls when doing a postback? Thanks.

Do the trace that I recommended.
Add a trace.warn that sees if it can find your master page property.
See what's happening.
See when it's there.
At the very least you will have a better understanding on how master and
content pages interact.

The only time I've done this sort of thing it was user data and I had a user
object.
The object was cached and the master page got values from out the cache.
Maybe that'd be something to consider.

What I know for sure is that you cannot refer to anything in a master page
within content page preinit.
The two are not merged.
 
Even though I still don't understand why I have two character for character
identical projects where one works and one doesn't, I am willing to accept
that the only way for me to make it work is to move the code that accesses
stuff in the master page from PreInit to one of the other events. However,
as I said in my previous post, the Init and Load events give me no errors on
the original page request, but the postbacks give the error that I talked
about when I started this thread:


When the code is in Init or Load, the original request works fine, but when
I do a postback it gives me the same problem I received on the original
request when it was in PreInit.


To summarize the situation so far, I receive the error on the original
request when I put the code in PreInit, and I receive the error on postback
when I put the code in Init or Load. What am I supposed to do? Thanks.
 
Nathan Sokalski said:
What am I supposed to do? Thanks.

You're supposed to spend 10 minutes investigating how master and content
pages interact so you understand it.
 
I have, and I think I do, but either way, I'm not sure what events are left
for me to put it in. If you don't want to or can't help me, then just don't
reply to the posts, the purpose of these newsgroups is to help our fellow
developers solve there problems, there is no better way to learn more about
anything than seeing the answer hands-on, even if you do need some help
figuring out what that answer is. Thanks.
 
Sorry man - forgot again :-(

I will send myself a reminder email - so you can expect some code tomorrow
if it is still required...
 
Back
Top