亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > .NET > 正文

asp.net Web站點風格切換的實現

2024-07-10 13:20:06
字體:
來源:轉載
供稿:網友
Web站點風格切換的實現引言

Web站點的風格切換是很常見、也很受大家歡迎的功能,比如大家熟知的博客園就提供了幾十款風格模板供大家選擇。在Asp.Net中,我們可以通過模板頁master page和主題theme來實現網站的風格切換,但是.Net提供的默認設置不夠強大和靈活。本文將向大家介紹如何在.Net提供的方法上進行改進和擴展,以提供更加強大的網站風格切換功能。

效果預覽:

NOTE:本文將master page稱為模板(有的書上叫母版),將theme稱為主題。

網頁的結構 和 模板、主題配置的局限靜態網頁的結構

網站的風格的切換,說白了,實際上就是對頁面進行分解和重組。所以在進行之前,我們先簡單回顧看一下頁面究竟有哪些組成部分可以供我們分解,分清楚哪些是可變的、哪些是不變的,進行后繼的工作才會容易得多?,F在我們先暫時脫離服務器端,看一下一個靜態的.htm頁面由哪幾部分組成:

結構(有語義的XHTML):這部分由XHTML標記組成,應該注意,這里使用“有語義”三個字作為修飾。XHTML的職責是告訴“這里是什么”,而不是告訴“這里應該如何顯示”。盡管瀏覽器對于幾乎每個XHTML的標記都賦予了某種內置的樣式控制,但是XHTML的本意只是規范文檔的結構。比如h1表示為標題,p表示為段落。而不是為了這個字顯示的更大一些才去使用h1。

表現和布局(CSS):CSS用來控制頁面的顯示及布局。在Web標準的概念普及以前,我想大多人都是表格套表格來布局的,現在基本都在使用CSS了,這里沒有太多好說的。

行為(Javascript):靜態網頁也可以添加一些交互的行為,這些行為由Javascript來完成。我們時常會把onclick="alert('hello')"這樣的代碼嵌入到XHTML標記中,比如一個Input標記上;一些結構、行為分離的狂熱人士則主張將行為與結構(XHTML)分離,他們不會將javascript代碼寫到<body>之間,而全部寫在了head中,或者是body下面,使用 window.onload=function(){ // …} 這種形式。有個極力主張這種做法的人(Peter-Paul Koch)寫了本書叫《》。

好了,大概了解了這些,我們看下.Net中如何將這三者分離,以及它的一些限制:

.Net對頁面結構的分離

我到現在都覺得 行為與結構 完全分離的概念太前衛了,另外它也不影響對網站的風格設置,所以我們這里不討論它。

我們先看一下結構:現在我們將思維向服務器端靠攏一下,很快會發現上面的結構部分仍需要再細分一次,就是XHTML標記和標記中的內容(網頁內容)分離。XHTML標記屬于變化的部分,不同的風格可能會需要不同的XHTML結構,而對于各個風格,它所顯示的內容顯然是一樣的。想要得到這樣的效果,我們可以使用Master Page模板頁。由Master Page模板頁對應XHTML結構(變化部分),由Page頁面對應于XHTML頁面的內容(不變部分),即是一個Page可以設置為不同的Master Page以達到不同的樣式(look and feel)。

NOTE:這里在說一下CSS,如果你的CSS水平足夠強,XHTML的代碼寫得足夠好,那么你無需搞得這么復雜,僅僅使用CSS就可以實現換膚了。有這樣的一個項目提供給全世界的人作為實踐,它提供一套統一的XHTML代碼,其他人則自己編寫CSS來對這個XHTML代碼進行樣式化,結果是百花齊放,一模一樣的XHTML實現了風格迥異的頁面設計。

現在在看一下表現部分,表現層分為全局式的CSS以及基于控件的皮膚Skin,這些都可以交由主題Theme來完成。

.Net 設置上的局限

看到這里,你可能覺得不用往下看了,使用Master Page和Theme誰不會啊?,F在我們就討論下.Net 中Master Page 和 Theme 的局限:

  • 大家知道,我們可以在 Web.config中的System.Web結點下的pages結點中添加Theme和masterPageFile屬性來對網站進行設置。但是它提供了一個全局性的配置,就是對于整個站點的所有頁面,都將使用這個Master Page。而有時候我們希望能夠每個頁面不相同,這里就無法實現了。雖然我們可以通過使用location結點來為各個頁面進行單獨設置,但是顯然太麻煩了。
  • 我們希望每個風格都有個名字,比如說“默認風格”、“春意盎然”。
  • 我們希望用戶可以選擇風格,而不是像博客園這樣由博主設置風格。
  • 實現網站的風格切換自定義風格配置

    有了思路后我們就來一步步地實現它,我們希望可以對風格進行簡單的設置,我們應該先明確需要設置的內容:我們都有哪些風格、當前使用的風格是什么、每個風格使用了什么主題、哪個頁面對應哪個模板。了解了這些之后,我們可以寫下這樣的結點配置來:

    <!-- MasterPage的 Path為 masterRoot + theme + master -->
    <!-- 不為Default設置masterPage,
         使用Default風格時會使用創建頁面時所選擇的Master Page -->
    <styleTemplates default="默認風格" masterRoot="~/MasterPage">
         <style theme="Default" ></style>
         <style theme="Spring" >
              <masterPages>
                   <page path="/website/default.aspx" master="Default.master" />
                   <!--<page path="/other.aspx" master="Default.master" />-->
                   <page path="/default.aspx" master="Default.master" />
              </masterPages>
         </style>
    </styleTemplates>

    styleTemplates是風格設置的根節點,default是默認的風格名稱;masterRoot是指模板頁的根目錄的地址;style結點是各個風格的名稱,以及其所使用的主題的名稱;style結點下的masterPages結點組包含此風格所使用的模板的信息;其中Page子結點對應每個獨立的頁面,path屬性記錄的是頁面的路徑,master屬性是每個頁面對應的模板的路徑。

    page結點的master屬性沒有給出模板的全路徑,這么做一個是為了使目錄結構更一目了然,還有就是不想master屬性的內容變得很長,所以需要在程序中指定頁面的模板的路徑為 masterRoot + Theme + masterPage名稱。這樣在模板的根目錄下,必須建立與主題同名的目錄,然后將模板位于該目錄下。

    在創建頁面時,我們需要要選擇一個模板。注意到這一點非常重要,因為這個模板實際上是該頁面的默認模板。當我們在Web.config中將相應風格的page結點留空時(沒有對此頁面設置模板),那么就會應用這個模板。所以在Web.Config中定義風格的模板,只是覆蓋了這個我們在創建頁面時選擇的模板。由此,我們只用定義一套完整的Master Page模板頁,供每個頁面在創建時選擇。而Web.config風格結點下設置的master page,實際上僅僅是動態地覆蓋這些模板。

    以上面的配置為例:當我們將 “春意盎然” 下的第二個 page 結點注釋掉時,它會應用創建頁面時所選擇的模板?!澳J風格”下面沒有設置任何的 page 結點,所以對于該風格的每個頁面,都會應用創建頁面時所選擇的模板。

    如果你希望僅使用Css來換膚,你可以使用也可以不使用Master Page,那么在Web.Config中可以像下面這樣設置:

    <styleTemplates default="默認風格" masterRoot="">
         <style theme="Default" ></style>
         <style theme="Spring" ></style>
         <style theme="Autumn" ></style>
    </styleTemplates>

    對于上面使用Master Page時的設置,站點的目錄結構如下所示:

    asp.net Web站點風格切換的實現

    可以看到模板頁的根目錄下包含了目錄Default、Spring與主題名稱相同(必須)。之后我們要編寫結點處理程序,如何編寫自定義結點處理程序,我在《.Net 自定義應用程序配置》一文中已經詳細的討論了,所以這里我們直接看實現,在AppCode目錄中新建一個文件StyleTemplateConfigHandler.cs:

    : IConfigurationSectionHandler
    {
        StyleTemplateConfiguration(section);
        }
    }

    {

        defaultTheme;    context;
        GetTheme(();
               doc.Load(context.Server.MapPath(@"~/web.config"));
               GetMasterPage(prepareMasterPath(string masterPath, string userTheme) {
           string path;

           if (node.Attributes["masterRoot"] != null)
               path = node.Attributes["masterRoot"].Value + "http://www.49028c.com/" + userTheme + "http://www.49028c.com/" + masterPath;
           else {
               if (userTheme != null) {
                  path = "~/" + userTheme + "http://www.49028c.com/" + masterPath;
               } else {
                  path = "~/" + masterPath;
               }
           }
           return path;
        }
    }

    這個類提供了一些簡單的對XmlNode的操作,對styleTemplates結點進行了映射,這里需要明確兩個概念:默認風格 和 用戶風格:

  • 默認風格,指的是站點管理員 或者 博主設置的風格,也就是Web.Config 中styleTemplates結點的Default屬性。
  • 用戶風格,用戶設置的風格,頁面的實際顯示是根據用戶風格而 不是默認風格。當用戶沒有設置風格時,才顯示默認風格。
  • 很顯然,這個類處理的所有的均是默認風格,我們來看一下它的幾個主要方法和屬性:

    GetTheme(DefaultStyle{}

    DefaultTheme { }

    GetMasterPage(string userTheme){}

    IUserStyleStrategy,獲取、設置用戶風格

    在繼續進行之前,我們來考慮這樣一個問題:因為我們要根據用戶選擇的風格來動態地為頁面加載主題和模板,那么用戶信息(用戶選擇了什么風格)應該保存在哪里,從哪里獲得呢?我們有很多的選擇:可以使用Session、可以使用Cookie,還可以保存到數據庫中。此時最好將這部分抽象出來,以便日后為不同的方法提供實現。我們定義一個接口 IUserStyleStrategy,它用來定義如何獲取、設置用戶風格,在AppCode中新建文件IUserStyleStragety.cs:

    {
        void ResetUserStyle(string styleName);  // 重新設置用戶風格
        string GetUserStyle();                     // 獲取用戶風格
    }

    然后我在這里提供了一個基于Cookie的默認實現:

    : context;

        (cookieName);

           cookie.Value = context.Server.UrlEncode(styleName);
           cookie.Expires = DateTime.Now.AddHours(2); ;
        }
    }

    如果日后你需要將信息保存在數據庫中,那么你只要重新實現一下這個接口就可以了:

    : ResetUserStyle(GetUserStyle() {
           throw new NotImplementedException();
        }
    }

    PageBase 類:繼承自Page的基類

    因為所有的頁面都要運行這樣的一個邏輯:判斷用戶是否有設置風格,如果沒有,使用Web.Config中設置的默認風格;如果設置了,使用用戶風格。最后動態地給Page類的Theme屬性和MasterPageFile屬性賦值。

    那么我們可以定一個基類,在這個基類中去做這件事,然后讓所有的頁面繼承這個基類;又因為頁面是一定要繼承自System.Web.UI.Page類的,所以這個基類也必須繼承自System.Web.UI.Page?,F在在AppCode中再建一個文件 PageBase.cs:

    : Page
    {
        userStyle;         userStrategy; OnPreInit(EventArgs e) {
           base.OnPreInit(e);

           // 這里會被緩存只在第一次時調用有用
           this.styleConfig = (StyleTemplateConfiguration)ConfigurationManager.GetSection("styleTemplates");

           // 當你實現了自己的 Strategy時只需要更改這里就可以了
           // 更好的辦法是將Stragey的類型保存在Web.config中,
           // 然后使用反射來動態創建
           userStrategy = new DefaultStyleStrategy("userStyle");

           // 獲取用戶風格
           userStyle = userStrategy.GetUserStyle();

           // 如果用戶沒有設置風格,使用默認風格
           if (String.IsNullOrEmpty(userStyle)) {
               userStyle = styleConfig.DefaultStyle;
               userTheme = styleConfig.DefaultTheme;
           } else {
               // 根據用戶設置的風格 獲取 主題名稱
               userTheme = styleConfig.GetTheme(userStyle);
           }

           // 根據當前頁獲取MasterPage的路徑
           string masterPagePath = styleConfig.GetMasterPage(userTheme);

           // 設置當前頁的MasterPage
           if (masterPagePath != null)
               this.MasterPageFile = masterPagePath;

           this.Theme = userTheme;      // 設置當前頁的主題
        }
    }

    這里需要注意:

  • ConfigurationManager.GetSection()方法只會調用一次,然后會將結果進行緩存;只要Web.Config不做修改,以后不管是Request還是PostBack都不會再重新生成StyleTemplateConfig的類型實例,而會從緩存中讀取。我在《.Net 自定義應用程序配置》中忘記說了。
  • userStrategy = new DefaultStyleStrategy("userStyle");這里可以將IUserStyleStrategy的類型信息保存在Web.config中,然后使用反射動態創建。具體方法依然參見《.Net 自定義應用程序配置》。
  • 如果想動態地為頁面設置主題和模板,代碼必須寫在PreInit事件中。參見《Asp.Net Page Life Cycle Overview》。
  • 效果預覽

    因為這只是一個范例程序,我主要是表達實現的思路,而不是代碼的編寫,所以省略了很多諸如結點屬性是否為空之類的判斷。下面的測試僅僅在Web.Config中的配置正確時。在站點下新建一個頁面,比如Default.aspx,注意創建一個模板頁,因為這里設置的是會被覆蓋的,所以無所謂選擇哪個模板。

    添加App_Theme下創建目錄Default、Spring,新建一個目錄MasterPage,在下面創建目錄Default、Spring,然后添加一些文件(這就不用我說了吧)。在頁面上添加一個DropDonwList,一個Button,當我們選擇要顯示的模板時,會進行相應的切換,編寫后置代碼:

    (styleName);
               Button1_Click(object sender, EventArgs e) {
        string styleName = ddlStyles.SelectedValue;
        userStrategy.ResetUserStyle(styleName); // 委托給userStragety去處理
    }

    之后你可以看到下面的畫面:

    asp.net Web站點風格切換的實現

    asp.net Web站點風格切換的實現

    可以通過下面這個連接來看實際的效果,注意到:在這里我讓 Default.aspx 和 Other.aspx 使用了同一個模板,你也可以設置它們使用不同的模板。

    總結

    在這篇文章中,我簡單地向大家介紹了實現網站風格切換的一個思路。

    我們首先復習了網頁的結構,了解了.Net默認配置的不足。接著分三個步驟實現了網站的風格切換:處理配置結點的程序、獲取用戶風格的方法、以及通過基類繼承來為各個頁面設置風格。最后我們通過簡單的兩個頁面進行了下測試和預覽。

    感謝閱讀,希望這篇文章能給你帶來幫助!

    發表評論 共有條評論
    用戶名: 密碼:
    驗證碼: 匿名發表
    亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
    国产精品久久久久77777| 欧美大片va欧美在线播放| 成人两性免费视频| 欧美激情综合色| 92看片淫黄大片看国产片| 国产精品av免费在线观看| 欧美精品一区三区| 国产精品久久久久久一区二区| 国产精品自拍网| 日本精品久久中文字幕佐佐木| 欧美极品少妇xxxxⅹ喷水| 亚洲人成网站999久久久综合| 91精品国产自产在线| 欧美视频一区二区三区…| 91精品国产91久久久久福利| 欧美激情一区二区三区久久久| 久久久久久久一区二区三区| 亚洲精品wwwww| 国产日韩欧美在线视频观看| 欧美超级免费视 在线| 热99精品里视频精品| 中文一区二区视频| 国产精品video| 日韩精品在线第一页| 亚洲精品国产精品国自产在线| 国产精品十八以下禁看| 日韩欧美在线视频日韩欧美在线视频| 26uuu另类亚洲欧美日本一| 欧美激情精品久久久久久变态| 国产一区二区丝袜高跟鞋图片| 亚洲视频自拍偷拍| 精品亚洲国产成av人片传媒| 久久久亚洲欧洲日产国码aⅴ| 国产精品久久97| 久久99国产精品自在自在app| 在线播放亚洲激情| 日韩专区在线观看| 国产精品自在线| 日本一区二区三区四区视频| 欧美日韩亚洲网| 国产欧美久久久久久| 成人国产精品久久久久久亚洲| 欧美多人爱爱视频网站| 在线成人一区二区| 久久久久久伊人| 欧美成人黑人xx视频免费观看| 国产精品白嫩初高中害羞小美女| 亚洲欧美国产精品va在线观看| 欧美亚洲午夜视频在线观看| 欧美日韩亚洲精品一区二区三区| 97精品久久久中文字幕免费| 成人久久久久爱| 国产精品成人播放| 91日韩在线视频| 亚洲色图35p| 国产日韩欧美日韩| 欧美国产精品va在线观看| 69久久夜色精品国产7777| 久久九九全国免费精品观看| 精品色蜜蜜精品视频在线观看| 欧美午夜精品在线| 国产精品99久久久久久www| 欧美电影免费观看| 亚洲电影免费观看高清完整版在线观看| 国产精品老女人视频| 国产精品视频精品视频| 欧美激情按摩在线| 一区二区三区高清国产| 欧美日韩高清在线观看| 68精品久久久久久欧美| 国产精品精品久久久久久| 国产69久久精品成人看| 国产精品美女久久久久av超清| 国产精品观看在线亚洲人成网| 欧洲成人在线视频| 亚洲天堂男人的天堂| 久久精品中文字幕电影| 亚洲丝袜在线视频| 欧美性xxxxhd| 日韩成人在线免费观看| 午夜免费久久久久| 91精品久久久久久| 亚洲视频在线视频| 国产精品高潮呻吟久久av无限| 91精品国产91久久久久久吃药| 久久91精品国产91久久久| 亚洲成色777777在线观看影院| 91亚洲精品久久久久久久久久久久| 欧美日韩亚洲一区二| 亚洲国产古装精品网站| 欧美巨乳在线观看| 亚洲欧洲日韩国产| 一区二区在线视频| 91成人在线播放| 国内免费久久久久久久久久久| 一区二区欧美亚洲| 欧美性猛交xxxx黑人猛交| 久久久99久久精品女同性| 亚洲va欧美va国产综合久久| 全球成人中文在线| 操人视频在线观看欧美| 在线丨暗呦小u女国产精品| 欧美香蕉大胸在线视频观看| 亚洲精品中文字幕女同| 亚洲影视中文字幕| 久久精品一区中文字幕| 色中色综合影院手机版在线观看| 亚洲香蕉成人av网站在线观看| 亚洲国产第一页| 91欧美精品成人综合在线观看| 亚洲激情视频在线| 5566成人精品视频免费| 丝袜亚洲欧美日韩综合| 午夜精品久久久久久久99黑人| 亚洲一级一级97网| 国语自产偷拍精品视频偷| 正在播放欧美一区| 国产日韩在线精品av| 亚洲另类xxxx| 最近中文字幕mv在线一区二区三区四区| 亚洲国产欧美一区二区三区同亚洲| 欧美一级视频一区二区| 国产精品视频免费在线| 国产精品偷伦视频免费观看国产| 精品久久香蕉国产线看观看gif| 26uuu日韩精品一区二区| 在线成人免费网站| 97久久精品人搡人人玩| 午夜精品久久17c| 日韩av在线一区二区| 国产成人+综合亚洲+天堂| 国产美女精品视频免费观看| 97在线视频免费观看| 91地址最新发布| 爱福利视频一区| 国产精品成人国产乱一区| 在线精品视频视频中文字幕| 国产精品草莓在线免费观看| 欧美日韩在线看| 国产精品亚洲第一区| 26uuu亚洲伊人春色| 尤物九九久久国产精品的特点| 欧美性jizz18性欧美| 欧美中文在线免费| 久久久久久久网站| 久久在线免费视频| 亚洲女人天堂视频| 高清视频欧美一级| 亚洲黄色www网站| 久久久久久久久久久91| 亚洲成成品网站| 欧美成人免费小视频| 2019国产精品自在线拍国产不卡| 成人免费黄色网| 在线亚洲国产精品网| 国产精品色午夜在线观看| 国产亚洲欧美日韩一区二区| 国产网站欧美日韩免费精品在线观看| 亚洲成人精品av| 久久97久久97精品免视看| 欧美猛男性生活免费| 日韩中文字幕在线精品| 久久精品久久精品亚洲人| 91久久久久久久久久久久久|