ASP.Net 提供了主題皮膚這個東西,其實也就是換膚啦。可是網路上有很多人說這個東西雞肋,說這個東西在.aspx頁面中使用還行,卻不能在母板頁(MasterPage)中使用。是的,確實不能直接在MasterPage透過一個DDL的選擇來切換整個網站的主題,因為Page.Theme 這個屬性都是在PreInit(){}中設置,否則報錯,而MasterPage是不執行PreInit() 。
我做的這個實例希望能夠幫大家解決這個問題。為是大家能更好的理解我這個原始碼,以下簡單介紹一下。
先說下一個想法:我們的目的是要在MasterPage放個DropDownList,透過切換DropDownList ,(我這裡沒有用DropDownList,而是用Css模擬一個「DropDownList」 其中的每個項目裡放了一個LinkButton,每個LinkButtond的PostBackUrl的值都形如:"~/ThemeTool.aspx?Theme=主題名稱" )來改變整個網站的主題,而不是只改變當前頁面,就跟Discuz ! 的那個一樣,所以這個改變是全局的,但是是針對於當前線程的,即A用戶改變了主題,只對A有效,對B用戶沒有影響,所以我們不會動到配置文件,那我們很快想到的就是session ,對的,我們要把主題的名稱放到session裡,如Session["Theme"]="Blue" ;這樣每個頁面只要在Page_PreInit()裡去取得該Session的值,並賦給該頁面的Page.Theme屬性,就OK了。
當我們改變了"DropDowList"的選項,在我這裡實際上是點擊了不同的Linkbutton,也就是要改變主題的名稱了,也就是要改變Session["Theme"]的值了,這個「改變」的在哪裡執行呢?這是很關鍵的,是在LinkButton_Click()裡嗎?不是,因為重新取得Page.Theme必須在Page_PreInit()裡,而LinkButton_Click()是發生得很晚的,還在Load之後,更別說PreInit()了,所以我在這裡是將它跳到ThemeTool .aspx裡處理的,處理完了再重定向到原頁面,這樣就達到了在原頁面PreInit()之前改變了Session["Theme"]的值,請放心這一過程不會使ThemeTool加載到瀏覽器,我們看不到的,我們只是藉用了它的Page_PreInit(),用完立刻就走了,哈哈! !
好了,思路就這樣,下面再介紹下三個文件:
1.MasterPage.master ,在這個文件裡值得說的就是我那用Css模擬的"DropDownList" , 該"DropDownList" 的每個項裡都有個LinkButton ,每個LinkButtond的PostBackUrl的值都形如:" ~/ThemeTool.aspx?Theme=主題名稱" ,這樣每次改變"DropDownList" 的選項就會向ThemeTool.aspx傳去了新的Theme值,再由ThemeTool.aspx處理將這個新的Theme值存入Session 。
2.在App_Code資料夾裡有ThemeSkin.cs文件,裡面寫了兩個靜態方法:GetTheme(Page P) 和GetTheme(Page P),其中GetTheme(Page P)用來取得主題,這個方法在網站的每一個需要有主題的頁面(我這裡就是Default.aspx 和Default2.aspx l了)的Page_PreInit()裡被調用,參數P 是指調用該方法的頁面,是個Page類型的對象;ChangeTheme()用來切換主題,在ThemeTool.aspx.cs的Page_PreInit()裡被呼叫。
3.根目錄裡的ThemeTool.aspx這個頁面也是很重要的,主題的切換就是在它的Page_PreInit裡搞定的,誰叫MasterPage不執行PreInit呢^_^ 。裡面的程式碼很簡單,不信你去看
展開