Access Controls Contained in a MasterPage through a Content Page
Introduction
MasterPages are a great feature that's new to the .NET 2.0 framework. They simplify the process of applying a look and feel across multiple pages in your ASP.NET application. Before these came about making a change that would apply to all your pages was quite a task as you had to go around to each page and make the change manually. Not only was it inefficient but there was always the possibility that you would miss a page. Now you can make the change in one file and the change will automatically be reflected in all your content pages.
There are times when you want to be able to customize a portion of your masterpage from your content page. There is actually a couple ways to accomplish this task. Follow me in this article as I show you how.
The "FindControl" method
Every control in asp.net exposes a public method called "FindControl." The purpose of this method is to find a child control that isn't exposed by a property. The way it accomplishes this is by taking a string as input which is the ID of the control you want to locate and if the control is found return that control as an instance of the Control class. You will then need to cast this reference to the type of control you're looking for. If the method does not find a control with the specified ID then a null reference (in VB nothing) will be returned.
How can you put this to good use in your content pages? Let's say for example you have a label placed on your master page. You decide you want to modify the Text property of this label. First thing you would do is call the master's FindControl method passing the ID of the label control and casting the return value to a Label. It's best to check for a null reference before doing anything with the label. That way if it wasn't found you can handle the situation yourself instead of an exception being thrown. Below is an example of how to do this.
Control masterPageControl = Page.Master.FindControl("MyLabelID");
Label masterPageLabel = masterPageControl as Label;
if (masterPageLabel != null)
{
masterPageLabel.Text = "Some new text";
}
else
{
}
As you can see, once you have a reference to the label you can modify its properties just as if the control was contained in the content page. This method can be applied to any type of control contained in your master page or really any control as every control exposes the FindControl method.
Creating a public property to access controls
The FindControl method is nice and simple and if you only need to access a control from one page it's a good way to go. However, if you're going to be accessing the same control on multiple pages you might want to consider this next method which involves exposing a public property from your masterpage. This allows you to contain the logic in one spot and achieves a strongly-typed reference to the control. It also gives you the ability to limit modifications to a certain property of a control rather than letting the content page have a complete reference to the control.
Going back to our previous example if you only wanted to let content pages modify the text of the label then you could expose that property through your own public property. That way you don't have to turn over the whole control to the content page. Below is an example of a property to expose the text of the label.
public string MyLabelText
{
get
{
return MyLabel.Text;
}
set
{
MyLabel.Text = value;
}
}
If on the other hand you wanted to expose the whole control then you would implement the property in this way.
public Label MyLabel
{
get
{
return MyLabel;
}
}
Notice I made this property read-only as the content pages will not need to create a new label in this instance.
At this point we've only implemented half of this method. If you were to add a property to your masterpage in this manner, go to a content page's code-behind and try to access it by calling Page.Master.MyLabelText it would not work. The reason is this. By default the Master property of the Page returns an instance of the MasterPage type and not an instance of your specific masterpage type. This property doesn't know what masterpage is used until you tell it. This takes us to the other step of this method.
If you go to the source view of your content page at the top you'll of course see the page directive which begins like this "<%@ Page". Below that you can add a variety of directives which allow you to accomplish different things. We're interested in the "MasterType" directive. This lets you specify which masterpage the content page uses for purposes of your code. There's actually two ways to use this directive. The most common method you will use is to specify the VirtualPath for your masterpage. An example of this implementation would look like this.
<%@ MasterType VirtualPath="MasterPageVirtualPath" %>
The other option offered by this directive allows you to specify the type of the master page. Use this option when you have built a masterpage in another assembly or a class which is contained in the app_code directory.
<%@ MasterType TypeName="MasterPageTypeName" %>
You will need to include one of these implementations of the MasterType directive in every content page that will access your property.
Conclusion
That's all there is to it. Now you know two ways to access controls in your masterpage and the pros and cons so that you may decide which is the best method for you to implement.