zoukankan      html  css  js  c++  java
  • DotText阅读笔记换肤的实现

    DotText的换肤实现起来挺复杂的,阅读了代码后把这块的心得记录下来.

    1.先简单说哈结构,(详细的结构描述可以看"DotText源码阅读(6) --模版皮肤  ")
    其实就是一些用户控件.这里主要有个用户控件叫"PageTemplate.ascx"这个相当于是整套模版的Index.
    每套模版放在一个文件夹内(比如winxpBlue),"PageTemplate.ascx"和css这些在这个文件夹的根目录,然后用户控件组在这个文件夹下的Controls里面 ,注意,用户控件的后台代码不是
    跟ascx放在一起的,而是在网站根目录的UI\Controls下,也就是说各套模版共用同样的cs.

    2.再来说哈主要相关的页面和类.
    主要类就是Dottext.Web.UI.WebControls.MasterPage,这个类是整个换肤的主类,是个容器,是最关键的.它用来装载用户控件,具体操作下面再说
    另外一个类就是ContentRegion,这个类是个Panel下继承来的,主要用来装在"内容"的用户控件

    其实DotText在处理页面布局时,已经划分了好了,就是一个Head,一个Foot,一个LeftColumn(工具箱),还有一个"内容"(这个用来装载内容的,比如装载详细信息,信息列表之类的,而上面提到的ContentRegion就是用来装载这个的)

    现在看default.aspx的设置
    <%@ Page language="c#" Codebehind="default.aspx.cs" AutoEventWireup="false" Inherits="Dottext.Web.UI.Pages.DottextMasterPage"%>
    <%@ Register TagPrefix="DT" Namespace="Dottext.Web.UI.WebControls" Assembly="Dottext.Web" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
    <HTML>
     <HEAD>
      <title><asp:Literal ID="pageTitle" Runat="server" /></title>
      <meta content=".Text" name="GENERATOR">
      <link id="MainStyle" type="text/css" rel="stylesheet" runat="Server"/>
      <link id="SecondaryCss" type="text/css" rel="stylesheet" runat="Server"/>
      <link id="RSSLink" title="RSS" type="application/rss+xml" rel="alternate" runat="Server"/>
     </HEAD>
     <body>
      <form id="Form1" method="post" runat="server">
       <DT:MASTERPAGE id="MPContainer" runat="server">
        <DT:contentregion id="MPMain" runat="server">
         <asp:PlaceHolder id="CenterBodyControl" runat="server"></asp:PlaceHolder>
        </DT:contentregion>
       </DT:MASTERPAGE></form>
     </body>
    </HTML>

    这里default的后台Dottext.Web.UI.Pages.DottextMasterPage,一会我们再说这个干了什么.
    现在注意页面,一个MasterPage控件,里面包含了一个id为MPMain的ContentRegion的Panel,在Panel上有一个PlaceHolder.

    3,现在来说到底是怎么工作的
    在说明怎样工作之前,要看哈DotText的UrlReWriting(详细的可以看"dotText源码阅读(5)--URLreWrite和Handler ").DotText是用HttpHandle来实现UrlReWriting的 .
    注意:其实用户访问的每一个页面都是转向到default.aspx,而之所以显示不同的内容是因为模版上的ID为"MPMain"的ContentRegion装载了不同的用户控件而已.
    我们看哈WebConfig上关于Handle的Config上的设置
    <HandlerConfiguration defaultPageLocation="default.aspx" type="Dottext.Common.UrlManager.HandlerConfiguration, Dottext.Common">
      <HttpHandlers>

      <HttpHandler pattern="/articles/\d+\.aspx$" controls="viewpost.ascx,Comments.ascx,AnonymousPostComment.ascx,LoginPostComment.ascx" />
       <HttpHandler pattern="/articles/\w+\.aspx$" controls="viewpost.ascx,Comments.ascx,AnonymousPostComment.ascx,LoginPostComment.ascx" />
       <HttpHandler pattern="/PreviewPost.aspx$" controls="PreviewPost.ascx" />
       <HttpHandler pattern="/archive/\d{4}/\d{2}/\d{2}/\d+\.(aspx|htm)$" controls="viewpost.ascx,Comments.ascx,AnonymousPostComment.ascx,LoginPostComment.ascx" />
       <HttpHandler pattern="/archive/\d{4}/\d{2}/\d{2}/\w+\.(aspx|htm)$" controls="viewpost.ascx,Comments.ascx,AnonymousPostComment.ascx,LoginPostComment.ascx" />
       <HttpHandler pattern="/archive/\d{4}/\d{1,2}/\d{1,2}\.aspx$" controls="ArchiveDay.ascx" />
       <HttpHandler pattern="/archive/\d{4}/\d{1,2}\.aspx$" controls="ArchiveMonth.ascx" />
       <HttpHandler pattern="/archives/\d{4}/\d{1,2}\.aspx$" controls="ArticleArchiveMonth.ascx" />
       <HttpHandler pattern="/contact\.aspx$" controls="Contact.ascx" />
       <HttpHandler pattern="/AddToFavorite\.aspx$" handlerType="Page" pageLocation="AddToFavorite.aspx" />
       <HttpHandler pattern="/BlogSearch\.aspx$" controls="BlogSearch.ascx" />
       <HttpHandler pattern="/posts/|/story/|/archive/" type="Dottext.Web.UI.Handlers.RedirectHandler,Dottext.Web" handlerType="Direct" />
       <HttpHandler pattern="/gallery\/\d+\.aspx$" controls="GalleryThumbNailViewer.ascx" />
       <HttpHandler pattern="/gallery\/image\/\d+\.aspx$" controls="ViewPicture.ascx" />
       <HttpHandler pattern="/(?:category|stories)/(\w|\s)+\.aspx$" controls="CategoryEntryList.ascx" />
       <HttpHandler pattern="/favorite/(\w|\s)+\.aspx$" controls="FavoriteList.ascx" />
       <HttpHandler pattern="/(?:admin)" type="Dottext.Web.UI.Handlers.BlogExistingPageHandler, Dottext.Web" handlerType="Factory" />

      </HttpHandlers>
     </HandlerConfiguration>
     
     这里我只想说哈  <HttpHandler pattern="/PreviewPost.aspx$" controls="PreviewPost.ascx" />  类型的配置,  比如这里,我们访问PreviewPost.aspx,那么会
    在后台执行 Dottext.Common.UrlManager.HandlerConfiguration的GetHandle
    public virtual IHttpHandler GetHandler(HttpContext context, string requestType, string url, string path)
      {
                              .....................
                              .....................
          switch(items[i].HandlerType)
          {
           case HandlerType.Page://默认是Page

            return ProccessHandlerTypePage(items[i],context,requestType,url);
           case HandlerType.Direct:
            HandlerConfiguration.SetControls(context,items[i].BlogControls);
            return (IHttpHandler)items[i].Instance();
           case HandlerType.Factory:
            //Pass a long the request to a custom IHttpHandlerFactory
            return ((IHttpHandlerFactory)items[i].Instance()).GetHandler(context,requestType,url,path);
           default:
            throw new Exception("Invalid HandlerType: Unknown");
          }
                                  ..............................
                                  ....................

      }
      
      而由于这种  PreviewPost.aspx的HandlerType是Page,所以会执行 ProccessHandlerTypePage  .而这个主要执行的工作就是SetControls,即把配置中的这个 "PreviewPost.ascx"保存到HttpContext里面,方便初始化页面的时候调用(调用用GetControls方法);

    最后地址仍然是被转向到了default.aspx.
                     
             现在来看初始化default.aspx页面,首先装载用户控件,default.aspx的后台代码是Dottext.Web.UI.Pages.DottextMasterPage,  在OnInit里面执行InitializeBlogPage函数,在这里读取HttpContext里面保存的用户控件名,装载它到MPMain上,而对于default.aspx上的用户控件MasterPage所做的操作是这样的,首先由于在请求时会执行事件AddParsedSubObject,在这里把default.aspx上定义的所有ContentRegion变量存入变量contents里面(即"MPMain").
             然后在MasterPage的OnInit里面做了两件事:
              一个是BuildMasterPage,在这里从BlogConfig里读取模版路径(例如:"WinXPBlue\PageTempalte.ascx"),然后加载它.
              另一个是BuildContents,用来初始化框架上内容这块的. 根据contents里面存储的各个ContentRegion变量名和页面上已经装载的控件想比较,找到contents里面存储的那个ContentRegion变量(即"MPMain"),然后加载它.(注意:因为PageTemplate.ascx也定义了一个ID为MPMain的ContentRegion类的变量,这部做的其实就是加载PageTemplate里面定义的MPMain下的用户控件了)
      
      好了,现在重新来看哈整个执行过程
      1.访问PreviewPost.ascx
      2.将字符串"PreviewPost.ascx"加入到HttpContext
      3.转向到default.aspx
      4.default.aspx加载Context里面存储的 PreviewPost.ascx 到页面上的MPMain上.
      5.default.aspx装载MaterPage
      6.MasterPage加载PageTemplate.ascx,并把它里面的子控件都加载在自己的Controls上.由于MasterPage重写了AddParsedSubObject,所以Default.aspx上的MPMain不会出现在MasterPage的Controls里面
      7.MasterPage处理MPMain,将变量contents里面保存的default.aspx上的MPMain的控件剪切到从PageTemplate.ascx上加载的MPMain上去.
      8.到此default.aspx输出的就是这样的:Head,Foot,Left工具箱是从PageTemplate.ascx上加载来的,而"内容"这块是PreviewPost.ascx了.
      

  • 相关阅读:
    express基础介绍
    gruntjs
    小写转换大写(人民币)
    Elasticsearch学习系列之多文档操作mget
    java.util.Date和java.sql.Date的使用方法,转载
    spring学习IOC
    oracle10g手动创建scott(tiger)的方法(转)
    观察者模式
    简单工厂,工厂模式,抽象工厂
    win7主机+winxp虚拟机,虚拟机使用主机的无线网卡(转)
  • 原文地址:https://www.cnblogs.com/jasononline/p/1095613.html
Copyright © 2011-2022 走看看