2010-03-12 12 views
9

Me pregunto si es posible crear un método de extensión que tenga un comportamiento de funcionalidad & similar a Html.BeginForm(), ya que generaría una etiqueta Html completa , y podría especificar sus contenidos dentro de las etiquetas <% { & } %>.Crear método de extensión para producir etiquetas de apertura y cierre como Html.BeginForm()

Por ejemplo, podría haber una vista como:

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

Esta capacidad sería muy útil en el contexto de la funcionalidad que estoy tratando de producir con el ejemplo de la this question

Esto haría dame la capacidad de crear contenedores para los tipos que voy a ser

<% 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> 

<% } %> 

comprendo que esto producirá XHTML válido, pero yo creo que podría Hay otros beneficios que superan esto, especialmente dado que este proyecto no requiere que el XHTML valide a los estándares W3C.

Gracias

de Dave

Respuesta

14

No estoy seguro de cuánto valor que esto tiene sobre definir simplemente un elemento <div>, sino algo así como lo que

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

y utilizar como tal

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

mostrará

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

o sin atributos HTML

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

gracias, me faltaba lo viewcontext.writer! – koenmetsu

Cuestiones relacionadas