ASP.NET 3.5核心编程学习笔记(10):母版页
时间:2011-04-16 来源:辛勤的代码工
母版页是一种由应用程序级(和页面级)引用的特殊文件,包含页面的静态布局。每个子页面可自定义区域,引用母版页中特殊的占位符控件。子页面是代码块的结合,运行库会用它们来填充母版页。母版页的内容会合并到内容页中,二者合在一起动态生成新的页面类,响应用户请求。合并的过程发生在编译时,且只发生一次。
母版页与内容页的处理
母版页的使用使页面的处理和编译方式发生了少许变化。首先,基于母版页的页面有两个依赖项:内容页面的aspx源文件和母版页的master文件。如果两个页面中任意一个被更改,动态页面程序集都会被重建。虽然用户需要的URL为内容页,但发往浏览器的最终页面还需要使用母版页,并由内容页提供相应的替换内容。
母版页的编译
当用户请求映射到内容页的aspx资源时,ASP.NET运行库会跟踪aspx及母版页的依赖关系,该信息将存入在ASP.NET临时文件文件夹中创建的本地文件中。随后,运行库会对母版页的源代码进行解析,根据母版页中设置的语言,创建VB或C#类。该类继承于MasterPage或母版页的代码文件,随即被编译为程序集。如果在同一目录发现多个master文件,则统一处理。因此,不应将无用的母版页文件放在Web控件中--无论怎样它们都会被编译。
为用户生成最终页面的过程
任何绑定到母版页上的ASP.NET页面必须以特定结构构建--<asp:Content>标签外不允许出现服务器控件或文本。因此,该页面的布局看起来很像是内容元素的集合,每个元素都会绑定到母版页中不同的占位符。这种连接的建立是通过ID属性完成的。<asp:Content>元素充当控件容器,所有的标记都会被编译到模板中,并与母版页上相应占位符的属性相关联。
母版页是一种带有模板区域的特殊用户控件,MasterPage类继承于UserControl类。一旦实例化为用户控件,母版页最终会通过定义在内容页的标记填充其各模板的内容。随后,最终的控件会被添加到当前页面的控件树中。下图展示了用户得到的最终页面的结构:
嵌套的母版页
母版页可以与另一个母版页相关联,构成一种分层、嵌套的结构。若使用嵌套的母版页,任何子母版页应以纯内容的形式实现,且还要为下级内容页定义额外的ContentPlaceHolder控件。也就是说,子母版页是一种特殊的内容页,其包含<asp:Content>和<asp:ContentPlaceHolder>元素的结合体。
对于网站中能够实现的嵌套页数,在架构上并没有限制。从性能上讲,嵌套的深度对整体功能和解决方案可伸缩性的影响也基本可以忽略。因为只要最终页面依赖的源文件不被更改,页面只会在需要时编译,随后生成的程序集便可重用。
母版页属性的暴露
为在母版页中标识控件,为其添加runat属性并为该控件分配ID即可。但在内容页中可访问该控件吗?不能,访问母版页对象的唯一途径是通过Page类的Master属性。我们只能访问在母版页中的公共属性和方法。
示例代码:
public partial class SimpleWithProp : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{}
public string TitleBoxText
{
get{ return TitleBox.Text; }
set{ TitleBox.Text = value; }
}
}
母版页属性的调用
Page.Master属性代表有ASP.NET运行库引擎编译生成的母版页对象。该类与常规页面类似,其名称也遵循一个命名约定--ASP.XXX_master,其中XXX代表母版页文件的名称,通过设置@Master指令的ClassName属性,开发者可以重写这个默认的名称。示例代码:
<%@ Master Inherits="SimpleWithProp" Classname="MasterWithProp" %>
为能调用自定义的属性或方法,我们还需对Master属性返回的对象进行类型转换:
((ASP.MasterWithProp)Master).TitleBoxText = "Programming ASP.NET 3.5";
通过在内容页添加@MasterType指令,我们可以避免上述的类型转换。该指令告诉编译器Master属性的真正类型。如下所示:
<%@ Page Language="C#" MasterPageFile="SimpleWithProp.master" CodeFile="HelloMasterType.aspx.cs" Inherits="HelloMasterType" %>
<%@ MasterType VirtualPath="SimpleWithProp.master" %>
protected void Page_Load(object sender, EventArgs e)
{
Master.TitleBoxText = "Programming ASP.NET 3.5";
}
@MasterType指令支持两个互斥的属性:VirtualPath和TypeName。二都都用来对母版页类进行标识,前者通过URL,而后者通过类型名称。
母版页的动态变更
Page类上指向母版页文件的MasterPageFile是可读/写属性,我们可以且仅可以在页面PreInit事件中设置该属性,以实现母版页的动态变更。
示例代码:
protected void Page_PreInit(object sender, EventArgs e)
{
MasterPageFile = "simple2.master";
}
如果试图在其他地方设置MasterPageFile属性,则会抛出异常。
加载MasterPageFile属性所引用的文件内容后,Master属性会由运行库来设置。