實現自己的MasterPage和WebPart控制項,開發沒有aspx,ascx的web程式,全部由自訂控制項產生,並且支援MasterPage摸版功能。

來源:互聯網
上載者:User

    實現自己的MasterPage和WebPart控制項

    開發沒有aspx,ascx的web程式,全部由自訂控制項產生,並且支援MasterPage摸版功能。

 

    asp.net提供的MasterPage確實是一個好的功能,我也很需要這樣的東西,可是我想更多的擴充一下,以實現自己的MasterPage控制項。需要支援可以動態更改title,動態添加關鍵字,動態添加css, 動態添加script。這是個不錯的想法,如何??

 

    那麼我們回到asp.net伺服器控制項的架構上來,先來熟悉下它,理解它的生命週期,這個很重要,我可不開玩笑,因為我需要對它加以利用,動點小手術,因此你必須必須理解它,否則,請放下鍵盤,拿起你的吉他,一邊玩兒^_*。

 

    在你放下鍵盤那起吉他之前,請把我這篇文章看完,好了,在這裡我只談2.0的相關部分。

 

    ===================控制項生命週期開始===================
    控制項構造器
    初始化階段 Init事件
    -----載入檢視狀態
    -----載入回傳資料
    載入階段 Load事件
    -----引發資料修改事件
    -----引發回傳事件
    預產生階段 PreRender
    儲存檢視狀態
    產生階段
    卸載階段 Unload
    釋放
    ===================控制項生命週期結束===================

    以上的東西寫的文章已經很多了,我只憑記憶把他寫出來,不對的地方,大家指正。

    還有一個需要熟悉的東西就是控制項的渲染流程,你需要理解他,不管怎樣,你都要理解他,請暫時放下你的吉他,理解它,真的,實在太重要了。

    Control控制項暴露了一個公用的RenderControl(HtmlTextWrite write)方法,用與產生html到輸出資料流。
這個方法是這麼定義的,這裡我說的是2.0。
    RenderControl(HtmlTextWrite write)
    {
        if(可視)
        {
           繼續Render(write);
        }
    }

    看到了,如果當前控制項的Visible屬性設定為true的話,它才會調用Render方法,注意這個方法是受保護的,不是由你來調用的,不過你還是有機會調用他的,放心,繼續看下面。
    除非你繼承Control控制項,否則你只能近接的調用他,也就是由Page架構或是Control的RenderControl方法調用它。

    Render方法是這樣的:
    Render(HtmlTextWrite write)
    {
        繼續RenderChildren(write);   
    }

    看上去是去產生子控制項,確實如此,RenderChildren是這樣的:

    RenderChildren(HtmlTextWrite write)
    {
        foreach(Control control in Controls)
        {
            RenderControl(write); //這裡我近接的調用了Render方法,雖然你是受到保護的。可我還是調用啦
        }
    }

    看到了,RenderChildren裡面有回去了,原來Control控制項的渲染流程是這樣的啊,通過判斷自己的Contros屬性來不斷的調用,只到自己的所有子控制項都調用到,好傢夥。

    以上提到的是寫web伺服器控制項的必備知識,很基礎,但是你不可以小視他,一點要過他,你才會寫出好的控制項來。

 

    web開發的底層就是一堆的HTML標籤,無論是jsp還是asp.net都是對html某種方式的封裝,是HTML的產物,IE瀏覽器訪問web伺服器,最終我們接收到的還是html文本。IE然後通過渲染引擎解釋這些標籤,在螢幕上展現出來可見的效果。

 

    asp.net提供了很多伺服器控制項,提供了很多所見即所得 (WYSIWYG)的功能,豐富了web應用程式的開發。

 

    這些伺服器控制項架構,有些地方我們是可以利用的,就是說我們自己可以來擴充,寫出符合自己需求的控制項來。asp.net web Control帶有太多的樣式屬性,比如說Panel控制項,就有如Color,Width等各種屬性,因為它繼承於WebControl控制項。如果你需要這麼一個Panel類似的控制項 ,可是你有不需要那些從WebControl繼承而來的屬性,那麼好的選擇就是你直接繼承Control控制項,這個控制項只有基本的控制項架構,而沒有那些可見的web樣式屬性。

 

    恰好我需要這樣的控制項,因為我不需要那些可見的web樣式屬性,因為我要產生的控制項通過CSS檔案來控制的,也就是所有的空間都只輸出Div這個標籤。如果這樣的標籤:

    <div id="id" class="class">
        <div id="id_children" class="class_container">
            <ul><li></li></ul>
        </div>
        <div id="id_children" class="class_container"> </div>
    </div>

    如上,標籤時可以嵌套的。

 

    到這裡開始自己動手,建立自己的MasterPage控制項,因為我不需要樣式控制,所以我選擇繼承Control控制項,以便於利用他的架構模型和渲染模型。

    public class MasterControl : Control
    {
        #region //欄位
        protected string id;
        protected string title;
        protected string keyword;
        protected List<string> css;
        protected List<string> script;
        protected Page page;
        #endregion
        //略去N行代碼...
        #region //重寫基類方法
        protected override void Render(HtmlTextWriter writer){....}
        #endregion

        #region //私人方法
        private void GenericHeadHTML(HtmlTextWriter writer)
        {
            writer.AddAttribute("http-equiv", "Content-Type");
            writer.AddAttribute(HtmlTextWriterAttribute.Content, "text/html; charset=utf-8");
            writer.RenderBeginTag(HtmlTextWriterTag.Meta);
            writer.RenderEndTag();

            writer.WriteLine();

            writer.AddAttribute("http-equiv", "Content-Language");
            writer.AddAttribute(HtmlTextWriterAttribute.Content, "zh-CN");
            writer.RenderBeginTag(HtmlTextWriterTag.Meta);
            writer.RenderEndTag();

            writer.WriteLine();

            writer.AddAttribute(HtmlTextWriterAttribute.Name, "keywords");
            writer.AddAttribute(HtmlTextWriterAttribute.Content, keyword);
            writer.RenderBeginTag(HtmlTextWriterTag.Meta);
            writer.RenderEndTag();

            writer.WriteLine();

            writer.RenderBeginTag(HtmlTextWriterTag.Title);
            writer.Write(title.Remove(title.Length - 3));
            writer.RenderEndTag();

            writer.WriteLine();

            foreach (string itemCss in css)
            {               
                writer.AddAttribute(HtmlTextWriterAttribute.Rel, "stylesheet");
                writer.AddAttribute(HtmlTextWriterAttribute.Href, itemCss);
                writer.AddAttribute(HtmlTextWriterAttribute.Type, "text/css");
                writer.AddAttribute("media", "all");
                writer.RenderBeginTag(HtmlTextWriterTag.Link);
                writer.RenderEndTag();
                writer.WriteLine();
            }

            foreach (string itemScript in script)
            {
                writer.WriteLine("<script type=\"text/javascript\" src=\"" + itemScript +"\" ></script>");
            }
        }
        #endregion
    }

 

    namespace MINGMING.MUSIC.Contorls
    {
        public class MasterPage : MasterControl
        {
            #region //欄位
            protected ControlContainerBase headerLayout, contentLayout, footerLayout;
            #endregion

            #region //構造方法
            public MasterPage(Page page)
                : base(page)
            {
                headerLayout = new FooterLayout(this);
                contentLayout = new ContentLayout(this);
                footerLayout = new HeaderLayout(this);
            }
            #endregion
        }
    }

 

頁面調用測試:

        #region 欄位
        protected RequestContext requestContext; //web組件需要的請求上下文
        protected NewsPartZone news1, news2, news3, news4; //web組件
        protected MasterControl masterPage; //MasterPage模板控制項
        #endregion

        #region //重寫基類方法
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            requestContext = new RequestContext();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            Initialize(); //初始化
        }
        #endregion

        #region //初始化
        private void Initialize()
        {
            #region
            /*
            NewsEntity newsEntity = new NewsEntity();
            NewsCategoryEntity newsCategoryEntity = new NewsCategoryEntity();
            List<NewsEntity> newsList ;
            List<NewsCategoryEntity> newsCategorys ;
            int totalRecord;

            newsEntity.ID = 3;
            newsEntity.Title = "testTitle88888";
            newsEntity.Content = "testContent88888";
            newsEntity.Author = "liuming";
            newsEntity.ImageFilename = null;
            newsEntity.HTMLFilename = "888880100.html";
            newsEntity.Category.ID = 1;
            newsEntity.Template.ID = 1;

            newsBLL.Add(newsEntity);
            newsCategorys = newsCategoryBLL.GetAll();
            newsList = newsBLL.GetPage(1, true, 1, 10, out totalRecord);
            */
            #endregion

            masterPage = new MasterPage(this); //自訂的MasterPage控制項,為當前頁設定MasterPage
            masterPage.ID = "layout"; //頁面ID
            masterPage.Title = "test Title"; //頁面標題
            masterPage.Keyword = "key1,key2,key3"; //頁面關鍵字
            masterPage.Css.Add("/Resources/Css/main.css"); //當前頁面所需要的樣式表檔案
            masterPage.Script.Add("/Resources/Script/main.js"); //當前頁面所需要的指令檔

            requestContext.PageHit.PageIndex = 1; //組件需要的請求上下文
            requestContext.PageHit.PageSize = 2;

            news1 = new NewsPartZone(); //組件1
            news1.ID = "news_partzone"; //組件1 ID
            news1.IsShowHeader = true; //是否顯示組件的Header地區
            news1.Title = "組件1"; //Header地區的文字
            news1.Parent = masterPage.Controls[1] as ControlContainerBase; //組件的父容器
            news1.RequestContext = requestContext; //請求上下文
            news1.MasterPage = masterPage; //組件的MasterPage
            news1.Initialize(); //將所有子控制項加到控制項樹,然後將自己加到MasterPage裡面,也就是把自己加到Parent屬性所指向的對象

            requestContext.PageHit.PageIndex = 1;
            requestContext.PageHit.PageSize = 3;

            news2 = new NewsPartZone(); //組件2
            news2.ID = "news_partzone2";          
            news2.Title = "組件2"; //這個title不會顯示出來
            news2.Parent = masterPage.Controls[1] as ControlContainerBase;
            news2.RequestContext = requestContext;
            news2.MasterPage = masterPage;
            news2.Initialize();

            news3 = new NewsPartZone(); //組件3
            news3.ID = "news_partzone3";
            news3.IsShowHeader = true;
            news3.Title = "組件3";
            news3.Parent = masterPage.Controls[1] as ControlContainerBase;
            news3.RequestContext = requestContext;
            news3.MasterPage = masterPage;
            news3.Initialize();

            requestContext.PageHit.PageIndex = 1;
            requestContext.PageHit.PageSize = 4;

            news4 = new NewsPartZone(); //組件4
            news4.ID = "news_partzone3";
            news4.Title = "組件3"; //這個title不會顯示出來
            news4.Parent = masterPage.Controls[2] as ControlContainerBase;
            news4.RequestContext = requestContext;
            news4.MasterPage = masterPage;
            news4.Initialize();
        }
        #endregion

 

最終產生的網頁代碼如下:
下面的這個HTML標籤全部由程式產生,所有的字元,包括頭部地區的。都是從伺服器端動態產生出來的。

 

 

<!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>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta http-equiv="Content-Language" content="zh-CN" />
  <meta name="keywords" content="key1,key2,key3" />
  <title>
   test Title - this.owner.MasterPage.Title - this.owner.MasterPage.Title - this.owner.MasterPage.Title - this.owner.MasterPage.Title
  </title>
  <link rel="stylesheet" href="/Resources/Css/main.css" type="text/css" media="all" />
  <link rel="stylesheet" href="/Resources/Css/newsList.css" type="text/css" media="all" />
  <link rel="stylesheet" href="/Resources/Css/newsList.css" type="text/css" media="all" />
  <link rel="stylesheet" href="/Resources/Css/newsList.css" type="text/css" media="all" />
  <link rel="stylesheet" href="/Resources/Css/newsList.css" type="text/css" media="all" />
  <script type="text/javascript" src="/Resources/Script/main.js" ></script>
  <script type="text/javascript" src="/Resources/Script/news.js" ></script>
  <script type="text/javascript" src="/Resources/Script/news.js" ></script>
  <script type="text/javascript" src="/Resources/Script/news.js" ></script>
  <script type="text/javascript" src="/Resources/Script/news.js" ></script>

 </head>
 <body>
  <div id="layout">
   <div id="layout_footer">
    Page_Header - 這裡是頁頭
   </div>
   <div id="layout_content">
    <div id="news_partzone" class="partzone">
     <div id="news_partzone_header" class="partzone_header">
      組件1
     </div>
     <div id="news_partzone_content" class="partzone_content">
      <div id="news_list_container">
       <ul><li>網路歌曲“黑色巧克力“ 07 - 顏繪唐</li><li>網路歌曲“黑色巧克力“ 06 - 顏繪唐</li></ul>
      </div>
      <div id="page_hit">

      </div>

     </div>
    </div><div id="news_partzone2" class="partzone">
     <div id="news_partzone2_content" class="partzone_content">
      <div id="news_list_container">
       <ul><li>網路歌曲“黑色巧克力“ 07 - 顏繪唐</li><li>網路歌曲“黑色巧克力“ 06 - 顏繪唐</li><li>網路歌曲“黑色巧克力“ 05 - 顏繪唐</li></ul>
      </div>
      <div id="page_hit">

      </div>

     </div>
    </div><div id="news_partzone3" class="partzone">
     <div id="news_partzone3_header" class="partzone_header">
      組件3
     </div>
     <div id="news_partzone3_content" class="partzone_content">
      <div id="news_list_container">
       <ul><li>網路歌曲“黑色巧克力“ 07 - 顏繪唐</li><li>網路歌曲“黑色巧克力“ 06 - 顏繪唐</li><li>網路歌曲“黑色巧克力“ 05 - 顏繪唐</li></ul>
      </div>
      <div id="page_hit">

      </div>

     </div>
    </div>
   </div>
   <div id="layout_header">
    Page_Footer - 這裡是頁尾<div id="news_partzone3" class="partzone">
     <div id="news_partzone3_content" class="partzone_content">
      <div id="news_list_container">
       <ul><li>網路歌曲“黑色巧克力“ 07 - 顏繪唐</li><li>網路歌曲“黑色巧克力“ 06 - 顏繪唐</li><li>網路歌曲“黑色巧克力“ 05 - 顏繪唐</li><li>網路歌曲“黑色巧克力“ 04 - 顏繪唐</li></ul>
      </div>
      <div id="page_hit">

      </div>

     </div>
    </div>
   </div>

  </div>
 </body>
</html>

 

附圖片:

 

 

 

 

 

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.