** 动态加载用户控件的组件!(终结 ** ** MasterPages ** ** 技术) ** ** **
让我们来做个页面模版吧!有了模版是不是就可以统一了呢! Sure !
比如:模版页 Template.ascx 中我们留出中间一个部分,或者你想要留出的一个空间,让以后放入你想要的内容。
好了!那么在我们的页面 index.aspx 上我们就可以引用这个 Template.ascx, 然后在空出的部分放入我们特别的东西,当然最好是在空的地方我们插入另外一个页面如: List.ascx ,
当然我们在做个页面 MyArchive.aspx. 同样的我们引用这个 Template.ascx, 然后再在空出大那个地方我们插入了另外一个页面 Archive.ascx.
非常好。我们要的两个 index.aspx. 和 MyArchive.aspx 页面是不是一样的呢?就只有我们留空的那一个地方不一样而已。
当然这样的应用可以是各种各样,可以不用框架集而达到更完美的效果。而你的页面完全可以没有重复的东西。因为我们的页面完全是组装而成的!
那么有了这个美妙的想法之后我们就开始去实现。
技术点: 1 、怎么留出一个空间出来,然后还要让引用页找到这个空间。
2 、怎么引用模版而且还要找出留出的空间。
3 、怎么引用另外一页插入我们在模版页中留出的空间。
其实所有这些就需要用到三个组件,一个是用来保留的空间,一个是用来引用页面放入到我们保留出来的空间,这两个组件其实只是起到标记的作用而已。另一个也是主要的一个就是引用模版,然后处理引用页面并插入到模版中去。
1 、我们来解决的一个技术问题,留个空间很容易的就是 PlaceHolder , 那么我们还要考虑到 ID 的问题 , 因为我们还要找到这个地方,当然我们可能要留几个不同的地方,这样就很有必要处理一下 ID 的问题。那么扩展 PlaceHolder 同时继承 INamingContainer 。
我们取名为: PlugArea
那么这个主要做的事情有两件事,把本身保存起来,然后在第三个组件用到的时候取出来。
public class PlugArea : PlaceHolder , INamingContainer {
public override string ID {
get {
return base .ID;
}
set {
base .ID = value ;
AddToContext();
}
}
private static readonly String contextKey = "Region.MasterPages.Region" ;
private void AddToContext() {
if ( HttpContext .Current != null ) {
String myKey = contextKey + this .ID;
if ( HttpContext .Current.Items.Contains(myKey) ) {
throw new InvalidOperationException ( " 这个 ID'" + this .ID + "' 已经用了啦! ." );
} else {
HttpContext .Current.Items[myKey] = this ;
}
}
}
internal static PlugArea FindPlugArea( String ID ) {
if ( HttpContext .Current == null ) {
return null ;
}
return HttpContext .Current.Items[contextKey + ID] as PlugArea ;
}
}
那么我们的 Template.ascx 可以写成这样
< %@ Control %>
< %@ Register TagPrefix="Region" Namespace="Region.Controls" Assembly="Region.Controls" %>
< HTML >
< HEAD >
< title > 信息管理系统 < body leftmargin = " 0 " topmargin = " 0 " marginwidth = " 0 " marginheight = " 0 " > < form runat = " server " id = " Form1 " >
< table width = 800 align = center border = 0 cellpadding = 0 cellspacing = 0 >< tr >< td >
相同的第一部分 < tr >< td >
< Region:PlugArea id = " part1 " runat = " server " /> < tr >< td >
相同的第二部分 < tr >< td >
< Region:PlugArea id = " part2 " runat = " server " /> < tr >< td >
相同的第三部分
2 、引用模版页的时候,在里面标记以下我们保留的空间应该插入哪个页面,标记以下就可以了!具体的事情由引用模版页的组建来搞定。继承 PlaceHolder
组建起名: SignArea
两件事情:一、只需把 ID 设成我们要插入那个空间组件的 ID.
二、在后面把这个插入我们留出的空间的时候,把组建的路径设成一样的,避免路径不一样引起异常发生。
当然,我们要在这个 SignArea 内应用我们的页面。
public class SignArea : PlaceHolder {
internal string Directory;
public override string TemplateSourceDirectory {
get {
return Directory;
}
}
}
我们可以这样用:
< Region: SignArea id = " part1 " runat = " server " >
这里可以用我前面的文章讲 LoadSky 来来引用用户页面,或直接写内容放这里。
< Region: SignArea id = " part2 " runat = " server " >
同上第一部分。
3 、应用我们的模版页并处理其中的模块插入。
继承 PlaceHolder 继
命名: LoadTemplate
做事情:一、重载 AddParsedSubObject 事件,在记录 PlaceHolder 中的 SignArea
二、加载 Template 页。
三、根据 SignArea 的 id 找到 PlugArea (用 PlugArea 内的 FindPlugArea ,也就是为什么要用静态方法的原因 ),然后把 SignArea 插入到 PlugArea 中去。
这三件事做完事情也就做完了
看一下代码:
public class LoadTemplate : PlaceHolder {
&nb