views:

1412

answers:

5

I have a few pages on my asp.net website that I would like to turn off a control on the master page. Is there a way to communicate with the master page from a child page?

+2  A: 

Here's an example of how to communicate with Master Pages from Child Pages.

In the master page, create a property for the control you wish to access, say a label called lblUser...

public string MyProperty
       {
        set { lblUser.Text = value; }
       }

In the child page, access the property you have just created as in the following example...

((MyMaster)this.Master).MyProperty = "Text changed from Sub Page";

We are able to do this because the Master is simply a class that inherits System.Web.UI.MasterPage.

And the Label.Text property that we created is just a property of the Master class (this name will be the specific name of your current Master Page, in this case MyMaster).

Notice it won't work without a cast to your specific Master Page class and this is because you added a field that does not exist in System.Web.UI.MasterPage, the type of this.Master, but in your specific Master Class.

Joe
+1 to this! Same as my solution, only more elegant!
GenericTypeTea
A: 
this.Master.FindControl("controlid").dosomethinghere
Colin
-1 hard coding control names as strings is BAD
GenericTypeTea
+8  A: 

You need to use a MasterType directive in your page markup

<%@ MasterType TypeName="Namespace.Etc.MyMasterPage" %>

Then you will be able to access any public properties of the page's master page using

this.Master.PropertyIWantToIntefereWith...

Hope this helps

Mark Dickinson
I've been doing that through casting the Page object... this sounds SOOO much better! Thanks!
Telos
It was not clear to me where to determine the TypeName value so I used the VirtualPath option for the MasterType and it worked great. Thanks!
Lloyd
Never new this! Thanks Mark +1!
GenericTypeTea
+1 indeed!!! Didn't know about this either and it make it so much easier to work with some of the navigation elements in my app!
Dillie-O
+5  A: 

Easiest way is to setup a property on your master page that handles the on/off functionality when called. Then in your child page set the MasterType directive to get a strongly typed reference to your master page to bypass the need to cast.

Your child page would have:

<%@ MasterType VirtualPath="~/Site1.Master" %>

And to call the property of the master page:

Master.MyLabel = false; // or true

So on your master you could have:

public bool MyLabel
{
    get
    {
        return masterLabel.Enabled;
    }
    set
    {
        masterLabel.Enabled = value;
    }
}
Ahmad Mageed
Marks anser got me going on it but this is answer is how I was able to implement it. Thanks Ahmad.
Lloyd
Nice one. One thing you can do is go into your .designer.cs file and change the scope of the control there to public, then you have all properties to hand in your page logic. Also if you are exposing a public property, its usually best to use CamelCase, pascalCase is for private fields. :)
Mark Dickinson
@Mark: good info! I agree about the CamelCase, missed that. Fixed now.
Ahmad Mageed
+1 for you then :) Nice answer Ahmad.
Mark Dickinson
@Mark: it's best not to expose master page controls. What if the master page layout changes? Just expose a property, method or event.
John Saunders
@John - yeah that's best practice. I think Ahmad hit the nail on the head with his answer. I just wanted to illustrate that the controls can be exposed fully, but it is fair to say that this is not always wise, thanks :)
Mark Dickinson
This works beautifully for me. Only issue I have is that it seems like the label on the master is rendered before my child page_load changes its value. Result = no change to the label. Should I be doing this in a different routine?
Mike at KBS
A: 

I was looking for something similar, but this solution doesn't seem to work for me. I have a nested master page. Does this work for a nested master? When I implemented, it's not recognizing the control that I added to my master.