学习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
"
/>
这里就来了一个我以前没注意的控件了(看MSND).. 初步看来和Label没什么区别!
resourcekey获取或设置资源的名称,该名称可用作查找资源值的键, 这里是为了实现网站的本地化,所以我就不再深究了.
所以这里我完全可以用Label改写了.
现在我们来看它的cs代码:
protected
void
Page_Load(
object
sender, EventArgs e)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
if (Globals.ThemesSelectorID.Length == 0)
Globals.ThemesSelectorID = ddlThemes.UniqueID;
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ddlThemes.DataSource = Helpers.GetThemes();
ddlThemes.DataBind();
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ddlThemes.SelectedValue = this.Page.Theme;
}
这里,他在Globals.cs这个类中定义了一个静态变量:
public
static
class
Globals
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
public static string ThemesSelectorID = "";
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
static Globals()
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
}
}
这个静态变量用来取得ddlThemes的ID,再下一句是设置ddlThemes的数据源,看Helpers这个类
public
static
string
[] GetThemes()
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
if (HttpContext.Current.Cache["SiteThemes"] != null)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return (string[])HttpContext.Current.Cache["SiteThemes"];
}
else
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
protected override void OnPreInit(EventArgs e)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
string id = Globals.TemeSelectId;
if (id.Length > 0)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// 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]))
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
this.Theme = this.Request.Form[id];
this.Session["CurrentTheme"] = this.Theme;
}
else
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// 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();
}
}
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
base.OnPreInit(e);
}
}
好了.现在让页面的cs代码这样就好了.
public
partial
class
_Default: BasePage
//
继承自BasePage;
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
protected void Page_Load(object sender, EventArgs e)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
}
点击下载源文件 可以发现,现在站点的样式是统一的!
2:00 了.该睡了..明天还要上课呢..呵呵..