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" />

 这里就来了一个我以前没注意的控件了(看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这个类中定义了一个静态变量:
   public static class 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;
         }

      }

这里的功能就是搜索你的主题文件夹中有几个主题,下次你添了主题,其他的你什么都不要做了,主题自然会出现在页面上.

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);
        }

    }


好了.现在让页面的cs代码这样就好了.
public partial class _Default: BasePage //继承自BasePage;
{
    
protected void Page_Load(object sender, EventArgs e)
    
{        

    }

}

点击下载源文件 可以发现,现在站点的样式是统一的!
2:00 了.该睡了..明天还要上课呢..呵呵..
posted @ 2007-05-24 00:17  sliuqin  阅读(811)  评论(4编辑  收藏  举报