2011-08-25 40 views
22

我想創建一個幫助器,我可以像Helper.BeginForm()那樣在括號之間添加內容。我不介意爲我的幫手創建一個開始,結束,但它很簡單,容易做到這一點。創建MVC3 Razor Helper像Helper.BeginForm()

基本上什麼,我試圖做的是包裝這些標籤之間的內容,使他們呈現已經格式化

@using Html.Section("full", "The Title") 
{ 
This is the content for this section 
<p>More content</p> 
@Html.TextFor("text","label") 
etc etc etc 
} 

參數「全」是該div和「CSS ID標題「是該部分的標題。

除了做我正在做的事情之外,還有更好的方法來實現這個嗎?

在此先感謝您的幫助。

回答

36

這完全有可能。 MVC中使用Helper.BeginForm這種方式完成的方式是該函數必須返回實現IDisposable的對象。

IDisposable interface定義了一個名爲Dispose的單一方法,在對象被垃圾收集之前調用該方法。

在C#中,using關鍵字有助於限制對象的範圍,並在其離開作用域時儘快進行垃圾回收。所以,與IDisposable一起使用是很自然的。

你會想實現一個Section類,它實現了IDisposable。當它被構造時,它將不得不爲你的部分渲染開放標籤,並且在處理它時渲染閉合標籤。例如:

public class MySection : IDisposable { 
    protected HtmlHelper _helper; 

    public MySection(HtmlHelper helper, string className, string title) { 
     _helper = helper; 
     _helper.ViewContext.Writer.Write(
      "<div class=\"" + className + "\" title=\"" + title + "\">" 
     ); 
    } 

    public void Dispose() { 
     _helper.ViewContext.Writer.Write("</div>"); 
    } 
} 

既然該類型可用,則可以擴展HtmlHelper。

public static MySection BeginSection(this HtmlHelper self, string className, string title) { 
    return new MySection(self, className, title); 
} 
+0

你應該改名爲whatgoodisadispose !!! :) 非常感謝。我知道你必須實現iDisposable才能使用{},但從來沒有想過這一點。 非常感謝你再次 –

+1

啊,作家,這是做的伎倆。 –

4

這是我寫的一個小實用程序來做到這一點。它更通用一些,因此您可以將它用於任何標籤和任何屬性。它被設置爲HtmlHelper的擴展方法,因此您可以從Razor內部以及代碼內部直接使用它。

public static class WrapUtil 
{ 
    public static IDisposable BeginWrap(this HtmlHelper helper, string tag, object htmlAttributes) 
    { 
     var builder = new TagBuilder(tag); 
     var attrs = GetAttributes(htmlAttributes); 
     if (attrs != null) 
     { 
      builder.MergeAttributes<string, object>(attrs); 
     } 
     helper.ViewContext.Writer.Write(builder.ToString(TagRenderMode.StartTag)); 

     return new WrapSection(helper, builder); 
    } 

    private static IDictionary<string, object> GetAttributes(object htmlAttributes) 
    { 
     if (htmlAttributes == null) 
     { 
      return null; 
     } 
     var dict = htmlAttributes as IDictionary<string, object>; 
     if (dict != null) 
     { 
      return dict; 
     } 
     return HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); 
    } 

    private class WrapSection : IDisposable 
    { 
     private readonly HtmlHelper _Helper; 
     private readonly TagBuilder _Tag; 

     public WrapSection(HtmlHelper helper, TagBuilder tag) 
     { 
      _Helper = helper; 
      _Tag = tag; 
     } 

     public void Dispose() 
     { 
      _Helper.ViewContext.Writer.Write(_Tag.ToString(TagRenderMode.EndTag)); 
     } 
    } 
}