為Web程序實現皮膚的功能一直是一項長久不衰的話題。
實現的方法無外乎用模版引擎解析皮膚的模版生成頁面。
模版引擎也是多種多樣,千奇百怪。
不過我覺得Mvc自帶的Razor配合Visual Studio在體驗上是最爽的模版引擎。
Mvc的View解析其實就是一種模版解析行為,那么我們是否可以利用Mvc的View解析實現程序的換膚功能呢?這樣就不需要在另做模版解析的工作。
下面就簡單實現一個換膚的例子。
先實現一個普通的Mvc程序,然后再修改成帶皮膚切換的Mvc程序。
新建一個空的Mvc3項目。
實現HomeController下的IndexAction ,並提供一些數據。
public ActionResult Index()
{
ViewBag.Title = " 歡迎光臨博客園 ";
IList< string> news = new List< string>() {
" 系統性能優化一例 ",
" Cowboy 源碼分析(五) ",
" 在ASP.NET Web Application中使用App_Code文件夾引發的異常 ",
" android自定義組件之TopMenu ",
" 使用CSS和JQuery,模擬超鏈接的用戶單擊事件 "
};
ViewBag.News = news;
return View();
}
}
{
ViewBag.Title = " 歡迎光臨博客園 ";
IList< string> news = new List< string>() {
" 系統性能優化一例 ",
" Cowboy 源碼分析(五) ",
" 在ASP.NET Web Application中使用App_Code文件夾引發的異常 ",
" android自定義組件之TopMenu ",
" 使用CSS和JQuery,模擬超鏈接的用戶單擊事件 "
};
ViewBag.News = news;
return View();
}
}
新建IndexAction的View,並顯示Action提供的數據。
<
h1
>
@ViewBag.Title
</ h1 >
< ul >
@foreach (string str in ViewBag.News)
{
< li >@str </ li >
}
</ ul >
@ViewBag.Title
</ h1 >
< ul >
@foreach (string str in ViewBag.News)
{
< li >@str </ li >
}
</ ul >
項目的結構
項目運行結果:
到此一個普通的mvc程序就完了,下面我們再實現換膚功能。
修改_ViewStart.cshtml 文件如下。
@{
Layout = " Shared/_Layout.cshtml ";
}
Layout = " Shared/_Layout.cshtml ";
}
在View目錄下新建一個Skins目錄,用於存放皮膚文件。
在Skins目錄下新建兩個皮膚目錄,綠衣盎然,紅妝素裹。並把原View目錄下除Web.config外的文件所有文件分別復制到這兩個目錄下。
然后分別為兩套皮膚的_Layout.cshtml,加上不同的樣式。
紅妝素裹 _Layout.cshtml
<style type="text/css">
*
{
color: Red;
}
</style>
*
{
color: Red;
}
</style>
綠意盎然 _Layout.cshtml
<style type="text/css">
*
{
color: Green;
}
</style>
*
{
color: Green;
}
</style>
此時運行項目肯定是報錯的,提示找不到視圖文件。
下面我們就通過修改View的搜尋路徑,實現模版的切換。
修改Global.asax文件。
protected
void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
RegSkin( " 綠衣盎然 "); // 修改皮膚名換膚
}
public static void RegSkin( string skinName)
{
RazorViewEngine engine = ViewEngines.Engines.Where(e => e is RazorViewEngine).Single() as RazorViewEngine;
engine.ViewLocationFormats = engine.PartialViewLocationFormats = engine.MasterLocationFormats = new string[]{
" ~/Views/Skins/ "+skinName+ " /{1}/{0}.cshtml ",
" ~/Views/Skins/ "+skinName+ " /{1}/{0}.vbhtml ",
" ~/Views/Skins/ "+skinName+ " /{1}/Shared/{0}.cshtml ",
" ~/Views/Skins/ "+skinName+ " /{1}/Shared/{0}.vbhtml ",
" ~/Views/{1}/{0}.cshtml ",
" ~/Views/{1}/{0}.vbhtml ",
" ~/Views/Shared/{0}.cshtml ",
" ~/Views/Shared/{0}.vbhtml "
};
}
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
RegSkin( " 綠衣盎然 "); // 修改皮膚名換膚
}
public static void RegSkin( string skinName)
{
RazorViewEngine engine = ViewEngines.Engines.Where(e => e is RazorViewEngine).Single() as RazorViewEngine;
engine.ViewLocationFormats = engine.PartialViewLocationFormats = engine.MasterLocationFormats = new string[]{
" ~/Views/Skins/ "+skinName+ " /{1}/{0}.cshtml ",
" ~/Views/Skins/ "+skinName+ " /{1}/{0}.vbhtml ",
" ~/Views/Skins/ "+skinName+ " /{1}/Shared/{0}.cshtml ",
" ~/Views/Skins/ "+skinName+ " /{1}/Shared/{0}.vbhtml ",
" ~/Views/{1}/{0}.cshtml ",
" ~/Views/{1}/{0}.vbhtml ",
" ~/Views/Shared/{0}.cshtml ",
" ~/Views/Shared/{0}.vbhtml "
};
}
至此換膚功能已經完成。