Master pages are a superbe idea. But sometimes you need to access Master Page properties from the child page. Suppose, for instance, you have a button on the Master Page with a text that you want to be able to set:
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="MyDemoMaster.master.cs" Inherits="MasterPageDemo.MyDemoMaster" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:button id="btnWithText" runat="server" text="Button">
<asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>
In the Master Page, you can create a property like this:
public string ButtonText
{
get { return this.btnWithText.Text; }
set { this.btnWithText.Text = value; }
}
Unfortunately, if you try to find the property "Master.ButtonText" in the childpage, it won't be available since the "Master" property is of type System.Web.UI.Page, and that does not contain properties of your derived class "MyDemoMaster"
This, of course, can be solved by changing the Page_Load of the child page like this:
protected void Page_Load(object sender, EventArgs e)
{
MyDemoMaster m = Master as MyDemoMaster;
m.ButtonText = "My button text";
}
Congratulations. Your button shows the right text. And you have succeeded into locking your child page to a single master. Your web page will not run when you try to use another master page. Go back to programming class 101 and you don't get any cookies today ;-)
The right solution is: create an interface like this:
namespace MasterPageDemo
{
public interface IButtonText
{
string ButtonText { get;set;}
}
}
Open the code behind file of your Master Page and let it implement the interface:
public partial class MyDemoMaster : System.Web.UI.MasterPage, IButtonText
{
protected void Page_Load(object sender, EventArgs e)
{
}
public string ButtonText
{
get { return this.btnWithText.Text; }
set { this.btnWithText.Text = value; }
}
}
And then you make the Page_Load of the child page like this
protected void Page_Load(object sender, EventArgs e)
{
IButtonText m = Master as IButtonText ;
if( m != null ) m.ButtonText = "My button text";
}
Now the Master Page and Child Page are no longer coupled by name. Any Master Page implementing the IButtonText interface may be used as a Master Page for your child. Checking if it can be casted by testing m != null is a nice encore.