2010-03-12 13 views
9

Je me demande s'il est possible de créer une méthode d'extension ayant des fonctionnalités similaires à Html.BeginForm(), en ce sens qu'elle génèrerait une balise Html complète , et je pourrais spécifiquement son contenu à l'intérieur des étiquettes <% { & } %>.Créer une méthode d'extension pour produire des balises ouvertes et fermantes comme Html.BeginForm()

Par exemple, je pourrais avoir une vue comme:

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

Cette capacité serait très utile dans le contexte de la fonctionnalité que je suis en train de produire avec l'exemple this question

Ce serait me donner la possibilité de créer des conteneurs pour les types que je vais

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

<% } %> 

Je sais que cela produira XHTML valide, mais je pense qu'il pourrait y d'autres avantages l'emportent, d'autant plus que ce projet ne nécessite pas que le XHTML soit conforme aux standards du W3C.

Merci

Dave

Répondre

14

Pas tout à fait sûr quelle valeur cela a plus simplement définir un élément <div>, mais quelque chose comme si

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

et utiliser comme si

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

affichera

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

ou sans attributs HTML

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

merci, je manquais la chose viewcontext.writer! – koenmetsu