上一回我们已经了解了MasterPages的基本使用方法,但是在实际使用过程中我们也会发现,这样的模板还无法满足要求。
笔者首先遇到的问题是页面标题。
对于使用模板的Web窗体来说,它的页面标题应该怎样写?一般情况下,页面标题由HTML的标准元素TITLE标记指定,它存在于HEAD标记内。可现在只有模板控件内存在完整的HTML标记,其他窗体都仅仅是通过MasterPages“引用”了这些公共的HTML元素。那么页面标题应该写在哪里?
笔者首先在模板的<title></title>内添加了一个region,在窗体的相应content内添加了其自身的页面标题。
模板代码:
<%@ Register TagPrefix="mp" namespace="Microsoft.Web.Samples.MasterPages" assembly="MasterPages" %>
<html>
<head>
<title>
<mp:region id="regTitle" runat="server"></mp:region>
</title>
</head>
<body>
...
</body>
</html>
结果却发现,MasterPages并不会将regTitle的内容正确输出为页面标题,却在页面结果的开头显示了一段包含页面标题内容的<div>标记。笔者猜测MasterPages并不能正常输出<head>中的region,但是将title定义在<body>显然不是合法的HTML代码。
那么能不能通过在模板中的公共部分定义一个设置标题的客户端脚本函数,而在模板的后台代码中编写在客户端调用此客户端脚本函数,将应用模板的窗体中对应content的内容输出为此函数的参数,从而动态实现为窗体输出页面标题的功能呢?
笔者在模板的<body>中添加了一个隐藏的region,因为其对应的content并不需要输出到页面结果中被客户端显示。
<body>
<mp:region id="regTitle" runat="server"></mp:region>
...
</body>
同时在<head>内定义了一个设置页面标题的客户端脚本函数:
<head>
...
<script language=javascript>
function setTitle(title)
{
do***ent.title = title;
}
</script>
</head>
而在模板UserControl的Page_Load事件方法中,添加了如下代码:
if (regTitle.Controls.Count > 0)
{
System.Web.UI.LiteralControl title = (System.Web.UI.LiteralControl)regTitle.Controls[0].Controls[0]; // MasterPages会将content中的内容以LiteralControl放入一个Panel,而把这个Panel再放入region
this.Response.Write("<script language=javascript>setTitle('" + title.Text + "')</script>");
}
应用此模板的窗体,在它的<mp:contentcontainer>中添加id="regTitle"的<mp:content>定义页面标题:
<%@ Register TagPrefix="mp" namespace="Microsoft.Web.Samples.MasterPages" assembly="MasterPages" %>
<mp:contentcontainer runat="server" MasterPageFile="~/Template.ascx" id="Test">
<mp:content id="regTitle" runat="server">Test页面标题</mp:content>
<mp:content id="regContent" runat="server">窗体内容测试</mp:content>
</mp:contentcontainer>
在“MasterPages实用技巧”的下一篇里,你可以了解基于MasterPages的另一个模板前端控制技巧——自动生成页面自身的全局客户端脚本。
希望能给大家带来帮助,谢谢!