TheBeerHouse---加载主题
学习theBeerhouse的原代码,今天了解下动态加载主题.
从母板页中查看,主题切换由自定义控件ThemeSelector.ascx实现.
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ThemeSelector.ascx.cs" Inherits="MB.TheBeerHouse.UI.Controls.ThemeSelector" %>
<b><asp:Localize runat="server" ID="locTheme" meta:resourcekey="locThemeResource1" Text="Theme: "></asp:Localize></b>
<asp:DropDownList runat="server" ID="ddlThemes" AutoPostBack="True" meta:resourcekey="ddlThemesResource1" />
<b><asp:Localize runat="server" ID="locTheme" meta:resourcekey="locThemeResource1" Text="Theme: "></asp:Localize></b>
<asp:DropDownList runat="server" ID="ddlThemes" AutoPostBack="True" meta:resourcekey="ddlThemesResource1" />
这里就来了一个我以前没注意的控件了(看MSND).. 初步看来和Label没什么区别!
resourcekey获取或设置资源的名称,该名称可用作查找资源值的键, 这里是为了实现网站的本地化,所以我就不再深究了.
所以这里我完全可以用Label改写了.
现在我们来看它的cs代码:
protected void Page_Load(object sender, EventArgs e)
{
if (Globals.ThemesSelectorID.Length == 0)
Globals.ThemesSelectorID = ddlThemes.UniqueID;
ddlThemes.DataSource = Helpers.GetThemes();
ddlThemes.DataBind();
ddlThemes.SelectedValue = this.Page.Theme;
}
这里,他在Globals.cs这个类中定义了一个静态变量:{
if (Globals.ThemesSelectorID.Length == 0)
Globals.ThemesSelectorID = ddlThemes.UniqueID;
ddlThemes.DataSource = Helpers.GetThemes();
ddlThemes.DataBind();
ddlThemes.SelectedValue = this.Page.Theme;
}
public static class Globals
{
public static string ThemesSelectorID = "";
static Globals()
{
}
}
{
public static string ThemesSelectorID = "";
static Globals()
{
}
}
这个静态变量用来取得ddlThemes的ID,再下一句是设置ddlThemes的数据源,看Helpers这个类
public static string[] GetThemes()
{
if (HttpContext.Current.Cache["SiteThemes"] != null)
{
return (string[])HttpContext.Current.Cache["SiteThemes"];
}
else
{
string themesDirPath = HttpContext.Current.Server.MapPath("~/App_Themes");
// get the array of themes folders under /app_themes
string[] themes = Directory.GetDirectories(themesDirPath);
for (int i = 0; i <= themes.Length - 1; i++)
themes[i] = Path.GetFileName(themes[i]);
// cache the array with a dependency to the folder
CacheDependency dep = new CacheDependency(themesDirPath);
HttpContext.Current.Cache.Insert("SiteThemes", themes, dep);
return themes;
}
}
{
if (HttpContext.Current.Cache["SiteThemes"] != null)
{
return (string[])HttpContext.Current.Cache["SiteThemes"];
}
else
{
string themesDirPath = HttpContext.Current.Server.MapPath("~/App_Themes");
// get the array of themes folders under /app_themes
string[] themes = Directory.GetDirectories(themesDirPath);
for (int i = 0; i <= themes.Length - 1; i++)
themes[i] = Path.GetFileName(themes[i]);
// cache the array with a dependency to the folder
CacheDependency dep = new CacheDependency(themesDirPath);
HttpContext.Current.Cache.Insert("SiteThemes", themes, dep);
return themes;
}
}
这里的功能就是搜索你的主题文件夹中有几个主题,下次你添了主题,其他的你什么都不要做了,主题自然会出现在页面上.
ddlThemes.SelectedValue = this.Page.Theme;这句就是指定页面的主题为选择的主题了.
这里有一定值得注意的地方:
Theme 属性只能在 PreInit 事件之前进行设置,在 PreInit 事件之后设置 Theme 属性将引发 InvalidOperationException 异常。
指定的主题必须作为应用程序主题或全局主题存在。如果该主题不存在,则将引发 HttpException 异常。
为了让主题能够在PreInit事件中加载.我们再设计一个类Basepage:
public class BasePage : System.Web.UI.Page
{
protected override void OnPreInit(EventArgs e)
{
string id = Globals.TemeSelectId;
if (id.Length > 0)
{
// if this is a postback caused by the theme selector's dropdownlist,
// retrieve the selected theme and use it for the current page request
if (this.Request.Form["__EVENTTARGET"] == id &&
!string.IsNullOrEmpty(this.Request.Form[id]))
{
this.Theme = this.Request.Form[id];
this.Session["CurrentTheme"] = this.Theme;
}
else
{
// if not a postback, or a postback caused by controls other then
// the theme selector, set the page's theme with the value found
// in Session, if present
if (this.Session["CurrentTheme"] != null)
this.Theme = this.Session["CurrentTheme"].ToString();
}
}
base.OnPreInit(e);
}
}
{
protected override void OnPreInit(EventArgs e)
{
string id = Globals.TemeSelectId;
if (id.Length > 0)
{
// if this is a postback caused by the theme selector's dropdownlist,
// retrieve the selected theme and use it for the current page request
if (this.Request.Form["__EVENTTARGET"] == id &&
!string.IsNullOrEmpty(this.Request.Form[id]))
{
this.Theme = this.Request.Form[id];
this.Session["CurrentTheme"] = this.Theme;
}
else
{
// if not a postback, or a postback caused by controls other then
// the theme selector, set the page's theme with the value found
// in Session, if present
if (this.Session["CurrentTheme"] != null)
this.Theme = this.Session["CurrentTheme"].ToString();
}
}
base.OnPreInit(e);
}
}
好了.现在让页面的cs代码这样就好了.
public partial class _Default: BasePage //继承自BasePage;
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
点击下载源文件 可以发现,现在站点的样式是统一的! {
protected void Page_Load(object sender, EventArgs e)
{
}
}
2:00 了.该睡了..明天还要上课呢..呵呵..