5.模版与主题
往页面中加入模板页:
然后添加新的页面就可以应用模板:
在弹出的窗口中选择你要使用的模板页:
模板也的实质:是一个页面,只是页面中包含多个Container(容器)就是预留了一块块的占位符,供子页面填充,以提供一致的页面表现(模式)。就像在一个容器上挖掉一块,这一块留给子页面填充,这是每个运用模板的子页面会不同于其它子页面的部分。让我们看下母版页刚创建后的代码:
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage2.master.cs" Inherits="MasterPage2" %>
<!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></title>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<div>
<p>这里是模板页内容</p>
<p>接下来的是子页面的内容</p>
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>
可以看出这里母版页上给挖了两个洞,一个是head,另一个是ContentPlaceHolder1。
让我们来看下子页面:
<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="~/MasterPage.master" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<asp:Content ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
</asp:Content>
首先我们关注在页面顶端的引用声明行,MasterPageFile="~/MasterPage.master"表示应用的模板,下面可以看到与母版页ContentPlaceHolder对应的Content标记,其属性ContentPlaceHolderID正对应着母版页中ContentPlaceHolder的ID。他们就是这样子连接起来工作的,你往子页面的Content里面丢的东西其实就是塞到母版页那个相应的预留空间当中。
1) 打造自己的模板
就以我校新闻网为例,下面是新闻内容页面截图:
在查看代码:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>浙农林大新闻网 | 浙江农林大学新闻网</title>
<meta name="Copyright" content="This site's design and contents Copyright (c) 2010 东湖信息技术服务中心." />
<meta name="keywords" content="新闻网,新闻,浙江农林大学" />
<meta name="description" content="浙江农林大学新闻网网站,提供相关新闻服务的在线帮助和咨询." />
<meta name="copyright" content="东湖信息技术服务中心" />
<meta name="author" content="于夏桥" />
</head>
<body id="generic" class="default">
<div id="wrapper">
<div id="container">
。。。
<ul>
<li>
<a href="http://www.zafu.edu.cn">学校主页</a></li><li>
<a href='#' 。。。>设为首页</a>
</li>
<li>
<a href="http://eoa.zafu.edu.cn" >办公系统</a>
</li>
<li>
<a href="http://mail.zafu.edu.cn">邮件系统</a>
</li>
</ul>
</div>
</div>
<div id="header">
<div id="nav-global">
<ul>
<li><a href="/articles/3/">学校要闻</a></li>
<li><a href="/articles/75/">综合新闻</a></li>
<li><a href="/articles/39/">部门传真</a></li>
<li><a href="/articles/53/">学院快讯</a></li>
<li><a href="/articles/6/">图片新闻</a></li>
<li><a href="/articles/10/">创新创业</a></li>
<li><a href="/articles/54/">学术动态</a></li>
<li><a href="/articles/7/">师生风采</a></li>
。。。
</ul>
</div>
<div id="search_bar">
<form action="/search/" method="get" name="search">
<p align="center">
<input type='text' name='keyword' style="border:1px solid #FFF;180px;" size='40' maxlength='22' value=" 请输入关键字..." onFocus="this.value='';" />
<input type="image" name="submit" src="/static/front/default/images/search.png" align="absmiddle"></p>
</form>
</div>
<iframe id="image_frame_weather" name="weather_inc" src="http://tianqi.xixik.com/cframe/6" style="height:74px;" width="130" height="80" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
</div>
<div id="middle"></div>
<div id="header-bar"></div>
<!-- END Header -->
这里是一大堆新闻的内容。。
<!-- END #content-main -->
<div id="content-related" class="sidebar">
<h1 class="title">热点新闻</h1>
<ul>
<li class="first">
<span class="time"> </span>
<a href="/articles/3/18685/" target="_blank" title="文章标题:我校辅导员董杜斌荣获“2011全国高校辅导员年度人物”提名奖
作 者:李金花
点 击 率:3242" class="title-color0">
[<font color="blue">图</font>]我校辅导员董杜斌荣获“2011全国高校
</a></li>
<li>
<span class="time"> </span>
<a href="/articles/3/18687/" target="_blank" title="文章标题:我校科研项目获省科学技术一等奖 赵洪祝出席表彰大会并向我校颁发证书
作 者:陈桂鹏
点 击 率:2119" class="title-color0">
[<font color="blue">图</font>]我校科研项目获省科学技术一等奖 赵
</a></li>
这里一大堆上面这些东西,都是页面右侧的内容他们也属于模板页,在服务器端后台才能更新这些内容。
</div>
<!-- END #content-related -->
<div class="clear"></div>
</div>
<!-- END #columnwrap -->
<div id="footer-bar">
<table border="0" cellpadding="0" cellspacing="5" width="98%">
<tbody>
<tr>
<td width="30">
</td>
<td align="middle">
<a href="http://www.peopledaily.com.cn/" target="_blank" title="人民网"><img _png_class="" height="35" src="http://www.news.zju.edu.cn/images/link1.jpg" width="94" /></a></td>
<td align="middle">
<a href="http://www.xinhua.org/" target="_blank" title="新华网"><img _png_class="" height="35" src="http://www.news.zju.edu.cn/images/link3.jpg" width="94" /></a></td>
。。这里都是一些链接和链接的图片
</tbody>
</table>
</div>
<!-- END #footer -->
</div>
<!-- END #container -->
<div id="footer">
<p>
COPYRIGHT © 2011 浙江农林大学 <a href="http://www.ZAFU.EDU.CN">WWW.ZAFU.EDU.CN</a> 学校地址:浙江·杭州·临安市环城北路88号 邮编:311300 电话:0571-63732700<br />
浙ICP备05014577号 版权所有·设计制作:现代教育技术中心·更新维护:宣传部<a href="/admin/"><img src="/static/front/default/images/home/home.gif" /></a></p>
今日访问量统计:16702 总访问量统计:84022311 <a href="/feeds/latest/" target="_blank"><img src="/static/front/default/images/rss.png" align="absmiddle" /> 订阅RSS新闻</a></div>
</div>
</body>
</html>
总结;你可以清楚看到页面中都很清楚的标明了Conteainer,说明这个网页正式利用了母版页的技术,我们可以轻松的把他们截取过来。你要做的只是把所有的HTML代码替换刚刚创建的新母版页中对应部分,并且把如下部分做替换:
<!-- END Header -->
这里是一大堆新闻的内容。。
<!-- END #content-main -->
这段换成一个ContentPlaceHolder
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
并在<head>标记内加入一个容器:
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
这里就是用来存放子页面需要用到的脚本或布局文件的,这些脚本是每个子页面需要的,并且每个子页面都有不同的需要而不同,故要在Head标记中设此容器以增加脚本。
现在试试在子页面中的Content中加入一些内容,看看是不是有母版页的效果了?
2) 模板页代码改子页面内容,子页面代码改母版页内容
效果:
首先我们要在母版页和子页面中都放入一个Label和一个Button,
母版页:
<body>
。。。
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<br />
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
<p>这里是母版页的内容</p>
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
。。。
</body>
子页面:
<asp:Content ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<asp:Button ID="Button1" runat="server" Text="Button"
onclick="Button1_Click" />
<p>这里是内容页的内容</p>
</asp:Content>
实现的代码如下:
母版页:
Label myLabel = (Label)Page.Master.FindControl("ContentPlaceHolder1").FindControl("Label1"); myLabel.Text = "模板页改变内容ye";
内容页:
Label myLabel = (Label)Page.Master.FindControl("Label1"); myLabel.Text = "实现了内容页修改模板页";
可见,内容页内直接找到的会是母版页中的Label,因为母版页中设了ContentPlaceHolder1容器,子页面在容器内,要找到子页面的label只能先找到容器ContentPlaceHolder1然后在容器内找Label控件。
即先用this.Master.FindControl("MainContent") 定位到Label的相对位置然后在这里寻找Label
加入母版页这里的“this”意义已经不是从前了,this的第一个对象找到的应该是MasterPage中的控件,而不是aspx中的控件。因为Aspx其实是把内容放在其中一个Content上的子控件上,所以aspx页面只能算作是this的一个子控件,所以可以说“本子页面的真正this”= this.Master.FindControl("MainContent")。
这里有一篇文章阐述阐述FindControl方法和INamingContainers接口:http://www.odetocode.com/Articles/116.aspx
FindControl方法是在当前naming container查找指定ControlID对应的控件,该naming container是一个实现了INamingContainer接口的对象。
可以在该页的页指令中添加 Trace=Ture 指令来跟踪页面输出查看控件树。一个页面的控件树中,Page对象必然是顶级的naming container,但绝非必然是唯一的naming container。譬如当有GridView存在的话,GridView其实也是一个naming container,要找GridView中的一个ControlID,就不能用Page.FindControl,而得用[GridView对象].FindControl方法。
3) 主题的应用。
添加一个主题文件夹
在其中加入一些主题文件夹:我加了蓝色和红色的,因为程序只识别文件夹,所以不用一个主题文件夹实现多主题的切换。
如图,在加入两个皮肤文件来定义主题:
Blue.Skin:
<asp:Label BackColor="Black" runat="server" ForeColor="#66FF99" Font-Italic="True" Font-Bold="True" Font-Size="XX-Large"></asp:Label>
<asp:Label SkinId="blue" BackColor="Black" runat="server" ForeColor="#3333FF" Font-Size="XX-Large"></asp:Label>
Red.skin:
<asp:Label BackColor="Black" runat="server" ForeColor="#FF4499" Font-Italic="True" Font-Bold="True" Font-Size="XX-Large"></asp:Label>
<asp:Label SkinId="blue" BackColor="Black" runat="server" ForeColor="#DDAA00" Font-Size="XX-Large"></asp:Label>
然后,页面上设置一个下拉菜单选择主题:
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True"
onselectedindexchanged="DropDownList1_SelectedIndexChanged">
<asp:ListItem Value="Red">红¨¬色¦?</asp:ListItem>
<asp:ListItem Value="Blue">蓝¤?色¦?</asp:ListItem>
</asp:DropDownList>
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="ok" />
然后加入一些Label:
<asp:Label ID="Label2" runat="server" Text="21212121"></asp:Label>
<br />
<asp:Label ID="Label3" runat="server" Text="3333333"></asp:Label>
<br />
<asp:Label ID="Label4" runat="server" Text="44444444444444"></asp:Label>
<asp:Label SkinID="blue" ID="Label10" runat="server" Text="我是blue标记的特殊Lable"></asp:Label>
后台加入代码以切换主题:
protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { if (Request.Cookies["theme"] != null) { HttpCookie myCookie = Request.Cookies["theme"]; DropDownList1.SelectedValue = myCookie.Value; } } } /*PS:主题必须在页面加载前就加载,所以必须写在Page_PreInit()函数当中。我这里还用到了Cookie缓存技术,实现了关闭浏览器主题还是保存的功能。*/ protected void Page_PreInit(object sender, EventArgs e) { if (Request.Cookies["theme"] == null) { this.Page.Theme = "Blue"; return; } HttpCookie myCookie = Request.Cookies["theme"]; this.Page.Theme = myCookie.Value; } protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e) { if (Request.Cookies["theme"] == null) { HttpCookie myCookie = new HttpCookie("theme"); myCookie.Value = DropDownList1.SelectedValue; myCookie.Expires = DateTime.Now.AddDays(1); Response.Cookies.Add(myCookie); } else { HttpCookie myCookie = Request.Cookies["theme"]; myCookie.Value = DropDownList1.SelectedValue; myCookie.Expires = DateTime.Now.AddDays(1); Response.Cookies.Add(myCookie); } //Response.Redirect(Request.Url.ToString()); }