在上一节已经介绍过访问母版资源的两种方法,其中第二种方法使用简单快捷,但在某些情况下同样显得无能为力。
比如:一个页面需要三种布局风格,这可能就需要三个模板,由访问者决定使用哪一个模板,也就是说在页面开发的时候,还不知道将使用哪一个模板,使用 @ MasterType VirtualPath 也就无法确定 MasterPage 的类型。
我们可以这样做:
- 建立一个基类。
- 各个模板页派生自这个基类。
- 内容页通过 MasterPageFile 确定使用哪个模板,通过 @ MasterType TypeName 来使用基类类型处理这些模板的资源。
具体如下(只演示一个模板文件代码):
基类文件代码:
using System;
using System.Web.UI;
namespace MasterPageNameSpace
{
public
abstract class MasterPageClass : MasterPage
{
public
abstract void SetCurNavItem(int itemIndex);
}
}
注意使用的名称空间和类及方法的修饰限定符。
模板文件代码:
<%@ Master Language="C#" Src="m1.cs" Inherits="MasterPageNameSpace.MasterPageClass" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
public override void SetCurNavItem(int itemIndex)
{
nav.Items[itemIndex].Attributes.CssStyle.Add("color", "#FF0000");
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ContentPlaceHolder id="m_header" runat="server">
<asp:BulletedList ID="nav" runat="server">
<asp:ListItem Text="导航一"></asp:ListItem>
<asp:ListItem Text="导航二"></asp:ListItem>
</asp:BulletedList>
</asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID="m_content" runat="server">在
</asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID="m_footer" runat="server">
<p>版权所有</p>
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>
我们也可以通过 CSC 把基类文件编译成 DLL 放在 bin 目录下,或者将 .cs 文件放在 App_Code 目录下,然后指令中省略 Src。
内容文件代码:
<%@ Page Language="C#" MasterPageFile="MasterPage1.master" Title="首页" %>
<%@ MasterType TypeName="MasterPageNameSpace.MasterPageClass" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
Master.SetCurNavItem(0);
}
</script>
<asp:Content ID="content" runat="server" ContentPlaceHolderID="m_content">
<p>这里是首页的内容</p>
</asp:Content>
总结
我们访问模板文件中的资源有三种方法:
- 程序中利用强制类型对 Master 进行转换;
- 利用 @ MasterType VirtualPath;
- 利用 @ MasterType TypeName。