你可以在控制页中完成许多公共的编程任务:
-
对定义在控制页中的成员进行访问,这些成员中包括有控制页的公共属性和方法、或者子控件。
-
动态对控制页和内容页进行绑定。
访问控制页中的成员
为了对控制页的成员进行访问,Page
类暴露了一个 Master
属性。为了对内容页所指定的控制页中的成员进行访问,你可以使用 @ MasterType
指令创建一个强类型对象并对控制页进行引用。该指令允许你对指定的控制页进行定位。当页面创建了 Master
属性之后,该属性的类型就会被转换成被引用的控制页。
例如,你可以有一个名为 MasterPage.master 的控制页,该控制页的类名是 MasterPage_master
。那么你可以创建如下实例的 @ Page
和 @ MasterType
指令:
<%@ Page masterPageFile="~/MasterPage.master"%> <%@ MasterType virtualPath="~/MasterPage.master"%>
当你使用 @ MasterType
指令的时候,像如上实例中的那样,你可以使用如下实例对控制页的成员进行引用:
CompanyName.Text = Master.CompanyName;
在这之前,页面的 Master
属性的类型早已经被转换成 MasterPage_master
。
获取控制页中的控件属性值
在运行时,控制页会与内容页进行合并,所以控制页中的控件可以被内容页中的代码进行访问。(如果控制页中的 ContentPlaceHolder
控件中的子控件被内容页中的 Content
控件所重载,那么将无法对这些子控件进行访问。)因为这些控件是属于被保护级别的成员,所以这些控件不能够直接被当成控制页的成员进行访问。但是,你可以使用 FindControl
方法对控制页中的特定控件进行定位。如果需要访问的控件在控制页中的 ContentPlaceHolder
控件的内部,你必须首先获取 ContentPlaceHolder
控件的引用,然后再调用它的 FindControl
方法来获取控件的引用。
如下实例显示了如何才可以从控制页中获取控件的引用。该实例中的 ContentPlaceHolder
控件中只有唯一一个子控件被引用。
// 获取 ContentPlaceHolder 中的一个 TextBox 控件的引用 ContentPlaceHolder mpContentPlaceHolder; TextBox mpTextBox; mpContentPlaceHolder = (ContentPlaceHolder)Master.FindControl("ContentPlaceHolder1"); if(mpContentPlaceHolder != null) { mpTextBox = (TextBox) mpContentPlaceHolder.FindControl("TextBox1"); if(mpTextBox != null) { mpTextBox.Text = "TextBox 已找到!"; } } // 获取位于 ContentPlaceHolder 控件之外的一个 Label 控件的引用 Label mpLabel = (Label) Master.FindControl("masterPageLabel"); if(mpLabel != null) { Label1.Text = "控制页的标签 = " + mpLabel.Text; }
你可以使用 FindControl
方法对控制页的 ContentPlaceHolder
控件中的内容进行访问,如上实例所示。如果 ContentPlaceHolder
控件已经与 Content
控件的内容被合并,那么 ContentPlaceHolder
控件中将不再包含默认的内容。另外,它将包含被定义在内容页中的文本内容和控件。
动态绑定控制页
除了对控制页的引用进行声明(在 @ Page
指令中或配置文件中)之外,你还可以对控制页和内容页进行动态合并。因为控制页和内容页的合并过程发生在页面进程的初始化事件中,所以控制页的引用必须在此事件发生之前被指定。通常,你可以在 PreInit
事件中动态地指定被引用的控制页,如下实例所示:
void Page_PreInit(Object sender, EventArgs e) { this.MasterPageFile = "~/NewMaster.master"; }
控制页的动态强类型转换
如果内容页使用 MasterType
指令为控制页指定了一个强类型,那么该类型必须应用到任何一个动态指定的控制页中。如果你想要动态地对控制页进行选择,建议你为控制页的起源创建一个基类。然后在控制页基类中对公共的属性和方法进行定义。在内容页中,当你需要使用 MasterType
指令为控制页指定强类型的时候,请在基类中进行指定而不是在单独的控制页中。
如下实例显示了如何创建用于多个控制页的控制页基类型。该实例由一个继承自 MasterPage
控件的基类型、两个继承自基类型的控制页、以及一个允许用户使用 URL 查询串(?color=green)动态选择控制页的内容页。控制页基类定义了一个名为 MyTitle
的属性。另外。其中一个控制页已经对 MyTitle
属性进行了重载,而另一个没有。内容页把 MyTitle
属性用作页面的标题。页面的标题内容将会因此会对于被选择的控制页产生依赖。
如下实例是控制页基类型。
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public class BaseMaster : System.Web.UI.MasterPage { public virtual String MyTitle { get { return "BaseMaster 的标题"; } } }
如下实例是第一个控制页,它显示了兰色的背景。请留意 @ Master
指令中引用基类型的 Inherits
参数。
<%@ Master Language="C#" Inherits="BaseMaster" ClassName="MasterBlue" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <script runat="server"> // 没有任何属性对控制页基类的 MyTitle 属性进行重载。 </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server"> <title>无标题</title> </head> <body> <form id="form1" runat="server"> <div style="background-color:LightBlue"> <asp:contentplaceholder id="ContentPlaceHolder1" runat="server"> MasterBlue 的内容。 </asp:contentplaceholder> </div> </form> </body> </html>
如下实例是第二个控制页。几乎与第一个控制页一样,不同的是显示的背景色是绿色的,并且重载了定义在基类型中的 MyTitle
属性。
<%@ Master Language="C#" Inherits="BaseMaster" ClassName="MasterGreen" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <script runat="server"> public override String MyTitle { get { return "MasterGreen 的标题"; } } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" runat="server"> <title>无标题</title> </head> <body> <form id="form1" runat="server"> <div style="background-color:LightGreen"> <asp:contentplaceholder id="ContentPlaceHolder1" runat="server"> MasterGreen 的内容。 </asp:contentplaceholder> </div> </form> </body> </html>
如下实例是内容页,它允许用户使用 URL 查询串动态地对控制页进行选择。@ MasterType
指令为页面的 Master
属性指定了一个引用基类型的强类型。
<%@ Page Language="C#" Title="内容页" %> <%@ MasterType TypeName="BaseMaster" %> <script runat="server"> protected void Page_PreInit(Object sender, EventArgs e) { this.MasterPageFile = "MasterBlue.master"; if(Request.QueryString["color"] == "green") { this.MasterPageFile = "MasterGreen.master"; } this.Title = Master.MyTitle; } </script> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server"> 内容页的内容。 </asp:Content>