C# 封裝HtmlHelper組件:BootstrapHelper
前言:之前學習過很多的Bootstrap組件,博主就在腦海里構(gòu)思:是否可以封裝一套自己Bootstrap組件庫呢。再加上看到MVC的Razor語法里面直接通過后臺方法輸出前端控件的方式,于是打算仿照HtmlHelper封裝一套BootstrapHelper,今天只是一個開頭,講述下如何封裝自己的Html組件,以后慢慢完善。
一、揭開HtmlHelper的“面紗”
經(jīng)常使用Razor寫法的園友都知道,在cshtml里面,我們可以通過后臺的方法輸出成前端的html組件,比如我們隨便看兩個例子:
輸出成Html之后
博主的好奇心又來了,它是怎么做到的呢?于是將Html對象以及Label()方法轉(zhuǎn)到定義
由此可以看出Html對象是HtmlHelper類型的一個實例,而Label()方法則是HtmlHelper類型的一個擴展方法,所以就可以直接通過Html.Label()這種方式直接調(diào)用。
既然我們想要封裝自己的HtmlHelper,那么我們就必須要了解Label()方法里面是如何實現(xiàn)的,我們偉大的Reflector又派上用場了。我們來反編譯System.Web.MVC.dll看看。找到LabelExtensions這個類
經(jīng)過一系列的轉(zhuǎn)到定義,我們找到最終的方法
同樣,我們找到TextBox()最終定義的方法
喲西,原來就是TagBuilder這個一個小東西,讓人覺得神奇得不要不要的。所以有時我們需要敢于反編譯,或許看似高級的背后其實很簡單呢~~
二、BootstrapHelper組件封裝準備
1、定義BootstrapHelper
有了以上的基礎做準備,接下來就是具體的實現(xiàn)了,我們新建了一個空的MVC項目,添加如下文件。
編譯發(fā)現(xiàn)報錯如下
將HtmlHelper轉(zhuǎn)到定義發(fā)現(xiàn)它有兩個構(gòu)造函數(shù),分別有兩個、三個參數(shù)
那么,我們的BootstrapHelper也定義兩個構(gòu)造函數(shù),于是代碼變成這樣:
namespace Extensions
{
public class BootstrapHelper : System.Web.Mvc.HtmlHelper
{
/// <summary>
/// 使用指定的視圖上下文和視圖數(shù)據(jù)容器來初始化 BootstrapHelper 類的新實例。
/// </summary>
/// <param name="viewContext">視圖上下文</param>
/// <param name="viewDataContainer">視圖數(shù)據(jù)容器</param>
public BootstrapHelper(ViewContext viewContext, IViewDataContainer viewDataContainer)
: base(viewContext, viewDataContainer)
{ }
/// <summary>
/// 使用指定的視圖上下文、視圖數(shù)據(jù)容器和路由集合來初始化 BootstrapHelper 類的新實例。
/// </summary>
/// <param name="viewContext">視圖上下文</param>
/// <param name="viewDataContainer">視圖數(shù)據(jù)容器</param>
/// <param name="routeCollection">路由集合</param>
public BootstrapHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection)
: base(viewContext, viewDataContainer, routeCollection)
{ }
}
}
這樣通過子類復用父類的構(gòu)造函數(shù)的方式即可解決以上問題。編譯通過!
2、定義LabelExtensions
上面我們研究過HtmlHelper,在HtmlHelper里面,不同的html組件定義了不同的Extension(擴展),下面我們就以最簡單的Label標簽為例定義我們BootstrapHelper里面的Label標簽。
同樣,在Extensions文件夾里面我們新建了一個文件LabelExtensions.cs,用于定義Label標簽的擴展,它里面的基本實現(xiàn)如下:
namespace Extensions
{
public static class LabelExtensions
{
/// <summary>
/// 通過使用指定的 HTML 幫助器和窗體字段的名稱,返回Label標簽
/// </summary>
/// <param name="html">擴展方法實例</param>
/// <param name="id">標簽的id</param>
/// <param name="content">標簽的內(nèi)容</param>
/// <param name="cssClass">標簽的class樣式</param>
/// <param name="htmlAttributes">標簽的額外屬性(如果屬性里面含有“-”,請用“_”代替)</param>
/// <returns>label標簽的html字符串</returns>
public static MvcHtmlString Label(this BootstrapHelper html, string id, string content, string cssClass, object htmlAttributes)
{
//定義標簽的名稱
TagBuilder tag = new TagBuilder("label");
//給標簽增加額外的屬性
IDictionary<string, object> attributes = BootstrapHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
if (!string.IsNullOrEmpty(id))
{
attributes.Add("id", id);
}
if (!string.IsNullOrEmpty(cssClass))
{
//給標簽增加樣式
tag.AddCssClass(cssClass);
}
//給標簽增加文本
tag.SetInnerText(content);
tag.AddCssClass("control-label");
tag.MergeAttributes(attributes);
return MvcHtmlString.Create(tag.ToString());
}
}
}
我們暫且只定義一個方法,其他的重載我們很好擴展,這里給所有的BootstrapHelper里面的Label標簽統(tǒng)一添加了“control-label”樣式,當然,如果你的項目里面的label標簽定義了自己的樣式,那么這里改成你需要的樣式即可。以上代碼都比較基礎,這里就不一一講解。
3、定義BootstrapWebViewPage
以上定義了BootstrapHelper和LabelExtensions,準備工作是做好了,但是還少一個對象,比如我們在cshtml頁面里面@Html.Label("姓名")這樣寫,Html變量是一個HtmlHelper類型的對象,那么,如果我們需要使用類似@Bootstrap.Label()這種寫法,以此類推,Bootstrap變量應該也是一個BootstrapHelper類型的對象,那么如果我們要這么用,必須要先定義一個Bootstrap變量,這個變量到底在哪里定義呢。于是博主思考,Html變量是定義在哪里的呢?再次轉(zhuǎn)到定義
原來是在WebViewPage這個類的子類中,同樣,我們在Extensions文件夾里面也新建一個WebViewPage的子類BootstrapWebViewPage,實現(xiàn)代碼如下:
namespace Extensions
{
public abstract class BootstrapWebViewPage<T> : System.Web.Mvc.WebViewPage<T>
{
//在cshtml頁面里面使用的變量
public BootstrapHelper Bootstrap { get; set; }
/// <summary>
/// 初始化Bootstrap對象
/// </summary>
public override void InitHelpers()
{
base.InitHelpers();
Bootstrap = new BootstrapHelper(ViewContext, this);
}
public override void Execute()
{
//throw new NotImplementedException();
}
}
}
至于這里的泛型,我們以后再來做講解,這里先不做過多糾結(jié)
4、實踐
有了以上三步,所有需要的方法和變量都齊全了,貌似已經(jīng)“萬事俱備只欠東風”了,是不是這樣呢?我們來試一把
編譯,將Index.cshtml頁面關閉重新打開,發(fā)現(xiàn)仍然找不到Bootstrap對象
怎么回事呢,Html是可以找到的,那Bootstrap變量去哪里了呢。。。
經(jīng)過一番查找資料,發(fā)現(xiàn)在View文件夾里面有一個web.config文件(之前一直沒怎么在意這個東西,現(xiàn)在想想里面還是有學問的哦),里面有一個節(jié)點system.web.webPages.razor下面有一個pages節(jié)點,默認是這樣的:
<system.web.webPages.razor> <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <pages pageBaseType="System.Web.Mvc.WebViewPage"> <namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> <add namespace="BootstrapHelper" /> </namespaces> </pages> </system.web.webPages.razor>
我們將pages節(jié)點的pageBaseType改成我們的WebViewPage
<system.web.webPages.razor> <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <pages pageBaseType="Extensions.BootstrapWebViewPage"> <namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> <add namespace="BootstrapHelper" /> </namespaces> </pages> </system.web.webPages.razor>
然后編譯,重新打開Index.cshtml。
OK,可以找到Bootstrap對象了。我們將Index.cshtml里面寫入如下內(nèi)容:
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
@Html.Label("姓名")
@Html.TextBox("a", "Jim")
@Bootstrap.Label(null, "Bootstrap Label標簽", null, null)
</div>
</body>
</html>
運行看看效果:
怎么還是報錯呢?這個問題應該不難理解,因為在razor里面使用@調(diào)用后臺變量和方法的時候也存在命名空間的概念,這個命名空間在哪里引用呢,還是在View文件夾里面的web.config里面,在system.web.webPages.razor節(jié)點下面存在namespace的節(jié)點,我們將自定義的Label()擴展方法所在的命名空間加進去即可。于是配置變成這樣:
<system.web.webPages.razor> <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <pages pageBaseType="Extensions.BootstrapWebViewPage"> <namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> <add namespace="BootstrapHelper" /> <add namespace="Extensions"/> </namespaces> </pages> </system.web.webPages.razor>
再次運行
三、BootstrapHelper組件完善
通過上面一系列發(fā)現(xiàn)坑、填坑的經(jīng)歷,一個最最簡單的BootstrapHelper組件已經(jīng)基本可用。我們將LabelExtensions簡單完善下:
namespace Extensions
{
public static class LabelExtensions
{
public static MvcHtmlString Label(this BootstrapHelper html, string id)
{
return Label(html, id, null, null, null);
}
public static MvcHtmlString Label(this BootstrapHelper html, string content)
{
return Label(html, null, content, null, null);
}
public static MvcHtmlString Label(this BootstrapHelper html, string id, string content)
{
return Label(html, id, content, null, null);
}
public static MvcHtmlString Label(this BootstrapHelper html, string id, string content, object htmlAttributes)
{
return Label(html, id, content, null, htmlAttributes);
}
/// <summary>
/// 通過使用指定的 HTML 幫助器和窗體字段的名稱,返回Label標簽
/// </summary>
/// <param name="html">擴展方法實例</param>
/// <param name="id">標簽的id</param>
/// <param name="content">標簽的內(nèi)容</param>
/// <param name="cssClass">標簽的class樣式</param>
/// <param name="htmlAttributes">標簽的額外屬性(如果屬性里面含有“-”,請用“_”代替)</param>
/// <returns>label標簽的html字符串</returns>
public static MvcHtmlString Label(this BootstrapHelper html, string id, string content, string cssClass, object htmlAttributes)
{
//定義標簽的名稱
TagBuilder tag = new TagBuilder("label");
//給標簽增加額外的屬性
IDictionary<string, object> attributes = BootstrapHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
if (!string.IsNullOrEmpty(id))
{
attributes.Add("id", id);
}
if (!string.IsNullOrEmpty(cssClass))
{
//給標簽增加樣式
tag.AddCssClass(cssClass);
}
//給標簽增加文本
tag.SetInnerText(content);
tag.AddCssClass("control-label");
tag.MergeAttributes(attributes);
return MvcHtmlString.Create(tag.ToString());
}
}
}
呵呵,是不是有模有樣~~可能又有人要說博主“山寨”了,呵呵,不管山寨不山寨,你覺得爽就行。
四、總結(jié)
這篇先到這里,一路填坑,基本功能總算可用。還有一些需要完善的地方,比如泛型,比如lamada表達式等等,來日方長,博主有時間完善下。還有最基礎的一些表單控件,我們都需要封裝,這個估計還有點工作量,只能慢慢來完善了,等完善都一定的程度會開源在git上,希望自己能夠堅持下去!如果你覺得本文對你有幫助,請幫忙推薦下,您的推薦是博主堅持完善的動力。
以上所述是小編給大家介紹的C# 封裝HtmlHelper組件之BootstrapHelper ,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對我們網(wǎng)站的支持!
上一篇:C#環(huán)形緩沖區(qū)(隊列)完全實現(xiàn)
欄 目:C#教程
本文標題:C# 封裝HtmlHelper組件:BootstrapHelper
本文地址:http://www.jygsgssxh.com/a1/C_jiaocheng/6315.html
您可能感興趣的文章
- 01-10C#操作LINQ to SQL組件進行數(shù)據(jù)庫建模的基本教程
- 01-10C# 面向?qū)ο笕筇匦裕悍庋b、繼承、多態(tài)
- 01-10適用于WebForm Mvc的Pager分頁組件C#實現(xiàn)
- 01-10C#組件系列 你值得擁有的一款Excel處理神器Spire.XLS
- 01-10C#實現(xiàn)的微信網(wǎng)頁授權(quán)操作邏輯封裝示例
- 01-10C#Url操作類封裝、仿Node.Js中的Url模塊實例
- 01-10談一談autofac組件的實例范圍
- 01-10C# 重寫ComboBox實現(xiàn)下拉任意組件的方法
- 01-10C#使用第三方組件生成二維碼匯總
- 01-10C#通過第三方組件生成二維碼(QR Code)和條形碼(Bar Code)


閱讀排行
本欄相關
- 01-10C#通過反射獲取當前工程中所有窗體并
- 01-10關于ASP網(wǎng)頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實現(xiàn)txt定位指定行完整實例
- 01-10WinForm實現(xiàn)仿視頻播放器左下角滾動新
- 01-10C#停止線程的方法
- 01-10C#實現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實現(xiàn)讀取注冊表監(jiān)控當前操作系統(tǒng)已
隨機閱讀
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-10SublimeText編譯C開發(fā)環(huán)境設置
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 04-02jquery與jsp,用jquery
- 01-10delphi制作wav文件的方法
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10C#中split用法實例總結(jié)
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改


