2010-03-12 10 views
9

Zastanawiam się, czy można utworzyć metodę rozszerzenia, która ma funkcjonalność & zachowanie podobne do Html.BeginForm(), ponieważ generuje kompletny znacznik HTML , a ja mogłem sprecyzować jego zawartość w tagach <% { & } %>.Utwórz metodę rozszerzenia, aby utworzyć znaczniki otwarte i zamykające, takie jak Html.BeginForm()

Na przykład, mogę mieć widok jak:

<% using(Html.BeginDiv("divId")) %> 
<% { %> 
    <!-- Form content goes here --> 
<% } %> 

Możliwość ta będzie bardzo przydatna w kontekście funkcjonalności staram się produkować na przykładzie w this question

To byłoby Daj mi zdolność do tworzenia pojemniki do typów, które będę

<% var myType = new MyType(123, 234); %> 
<% var tag = new TagBuilder("div"); %> 

<% using(Html.BeginDiv<MyType>(myType, tag) %> 
<% { %> 
    <!-- controls used for the configuration of MyType --> 
    <!-- represented in the context of a HTML element, e.g.: --> 

    <div class="MyType" prop1="123" prop2="234"> 
     <!-- add a select here --> 
     <!-- add a radio control here --> 
     <!-- whatever, it represents elements in the context of their type --> 
    </div> 

<% } %> 

Zdaję sobie sprawę, to będzie produkować nieprawidłowy XHTML, ale myślę, że nie może być innymi korzyściami, które przeważają nad tym, zwłaszcza, że ​​ten projekt nie wymaga, aby XHTML sprawdzał zgodność ze standardami W3C.

Dzięki

Dave

Odpowiedz

14

Nie pewny ile wartość ta ma ponad prostu definiowania elementu <div>, ale coś tak

/// <summary> 
/// Represents a HTML div in an Mvc View 
/// </summary> 
public class MvcDiv : IDisposable 
{ 
    private bool _disposed; 
    private readonly ViewContext _viewContext; 
    private readonly TextWriter _writer; 

    /// <summary> 
    /// Initializes a new instance of the <see cref="MvcDiv"/> class. 
    /// </summary> 
    /// <param name="viewContext">The view context.</param> 
    public MvcDiv(ViewContext viewContext) { 
     if (viewContext == null) { 
      throw new ArgumentNullException("viewContext"); 
     } 
     _viewContext = viewContext; 
     _writer = viewContext.Writer; 
    } 

    /// <summary> 
    /// Performs application-defined tasks associated with 
    /// freeing, releasing, or resetting unmanaged resources. 
    /// </summary> 
    public void Dispose() 
    { 
     Dispose(true /* disposing */); 
     GC.SuppressFinalize(this); 
    } 

    /// <summary> 
    /// Releases unmanaged and - optionally - managed resources 
    /// </summary> 
    /// <param name="disposing"><c>true</c> to release both 
    /// managed and unmanaged resources; <c>false</c> 
    /// to release only unmanaged resources.</param> 
    protected virtual void Dispose(bool disposing) 
    { 
     if (!_disposed) 
     { 
      _disposed = true; 
      _writer.Write("</div>"); 
     } 
    } 

    /// <summary> 
    /// Ends the div. 
    /// </summary> 
    public void EndDiv() 
    { 
     Dispose(true); 
    } 
} 


/// <summary> 
/// HtmlHelper Extension methods for building a div 
/// </summary> 
public static class DivExtensions 
{ 
    /// <summary> 
    /// Begins the div. 
    /// </summary> 
    /// <param name="htmlHelper">The HTML helper.</param> 
    /// <returns></returns> 
    public static MvcDiv BeginDiv(this HtmlHelper htmlHelper) 
    { 
     // generates <div> ... </div>> 
     return DivHelper(htmlHelper, null); 
    } 

    /// <summary> 
    /// Begins the div. 
    /// </summary> 
    /// <param name="htmlHelper">The HTML helper.</param> 
    /// <param name="htmlAttributes">The HTML attributes.</param> 
    /// <returns></returns> 
    public static MvcDiv BeginDiv(this HtmlHelper htmlHelper, IDictionary<string, object> htmlAttributes) 
    { 
     // generates <div> ... </div>> 
     return DivHelper(htmlHelper, htmlAttributes); 
    } 

    /// <summary> 
    /// Ends the div. 
    /// </summary> 
    /// <param name="htmlHelper">The HTML helper.</param> 
    public static void EndDiv(this HtmlHelper htmlHelper) 
    { 
     htmlHelper.ViewContext.Writer.Write("</div>"); 
    } 

    /// <summary> 
    /// Helps build a html div element 
    /// </summary> 
    /// <param name="htmlHelper">The HTML helper.</param> 
    /// <param name="htmlAttributes">The HTML attributes.</param> 
    /// <returns></returns> 
    private static MvcDiv DivHelper(this HtmlHelper htmlHelper, IDictionary<string, object> htmlAttributes) 
    { 
     TagBuilder tagBuilder = new TagBuilder("div"); 
     tagBuilder.MergeAttributes(htmlAttributes); 

     htmlHelper.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.StartTag)); 
     MvcDiv div = new MvcDiv(htmlHelper.ViewContext); 

     return div; 
    } 
} 

i używać jak tak

<% using (Html.BeginDiv(new Dictionary<string, object>{{"class","stripey"}})) 
{ %> 
     <p>Content Here</p> 
<% } %> 

wyświetli

<div class="stripey"> 
    <p>Content Here</p> 
</div> 

lub bez atrybutów HTML

<% using (Html.BeginDiv()) 
{ %> 
     <p>Content Here</p> 
<% } %> 
+0

dzięki, brakowało mi rzeczy viewcontext.writer! – koenmetsu

Powiązane problemy