3

Dans une application Asp.net MVC, je voudrais encapsuler le code wrapper laid (juste une chaîne d'ouverture html littérale et une autre chaîne de fermeture) que nous utilisons pour faire des coins et les ombres compatibles avec les anciens navigateurs (nous n'utilisons pas javascript pour des raisons de performances) d'une manière compatible avec la vue de conception de studio visuel. Je voudrais mettre les divs wrapper dans un contrôle afin que je puisse les utiliser dans une page de vue .aspx et ne pas avoir à regarder tout le désordre nécessaire pour faire des coins fantaisistes & mais toujours tirer profit de voir les résultats dans le concepteur.Début et fin de divs à l'aide de deux contrôles - Asp.net mvc

// emballage ouvert littérale contenu réel // wrapper près littérale

Je ne pouvais pas comprendre comment injecter du contenu dans 1 contrôle et ont des résultats visibles dans le concepteur des pages maîtres de façon faire, alors Je suis en train de tester un système utilisant 2 contrôles contenant le html littéral.

exemple d'utilisation - avec une ouverture de commande et une autre fermeture

<ShadowBoxStart /> //contains div open tags 
Hello World. This is actual content with all the nice style divs wrapped around 
<ShadowBoxEnd /> //contains div close tags 

Cela rend correctement dans tous les navigateurs quand je lance l'application, mais le concepteur semble être confondu par le fait que l'on commande ouvre les divs et un autre les ferme et rend la camelote. Les System.Web.Mvc.ViewUserControls que j'utilise ne contiennent rien d'autre que le littéral html, et j'ai répliqué le comportement avec plusieurs configurations différentes de style standard &, donc je suis perplexe quant à ce qui est source de confusion pour le concepteur. Je voudrais garder la solution très simple parce que c'est principalement une installation de commodité et ne vaut pas beaucoup de complexité ajoutée. Des idées?

Répondre

5

Avez-vous pensé à créer une extension HtmlHelper à la suite de l'extension BeginForm qui vous permettrait d'effectuer les simples balises d'ouverture/fermeture. Cette extension renvoie un objet d'une classe qui implémente IDisposable et utilise la méthode Dispose pour générer la balise de fermeture.

Ensuite, votre HTML ressemblerait à ceci:

<% using (Html.ShadowBoxStart()) { %> 
    Hello, World! 
<% } %> 

Une partie du code que vous pourriez être en mesure d'adapter:

public static class HtmlHelperExtensions 
{ 
    /// <summary> 
    /// Begins a container block using the specified tag. Writes directly to the response. Expected to be used within a using block. 
    /// </summary> 
    /// <param name="helper">HtmlHelper object from a View.</param> 
    /// <param name="tag">The container tag (div, span, hN, etc.)</param> 
    /// <returns>An MvcContainer that writes the closing tag when it is disposed.</returns> 
    public static MvcContainer BeginContainer(this HtmlHelper helper, string tag) 
    { 
     return BeginContainer(helper, tag, null); 
    } 

    /// <summary> 
    /// Begins a container block using the specified tag. Writes directly to the response. Expected to be used within a using block. 
    /// </summary> 
    /// <param name="helper">HtmlHelper object from a View.</param> 
    /// <param name="tag">The container tag (div, span, hN, etc.)</param> 
    /// <param name="htmlAttributes">HTML attribute to apply to the tag.</param> 
    /// <returns>An MvcContainer that writes the closing tag when it is disposed.</returns> 
    public static MvcContainer BeginContainer(this HtmlHelper helper, string tag, object htmlAttributes) 
    { 
     var builder = new TagBuilder(tag); 
     builder.MergeAttributes(new ParameterDictionary(htmlAttributes)); 
     helper.ViewContext.HttpContext.Response.Write(builder.ToString(TagRenderMode.StartTag)); 
     return new MvcContainer(helper.ViewContext.HttpContext.Response, tag); 
    } 
} 

classe Container:

/// <summary> 
/// Used by the HtmlHelpeExtensions in conjunction with a using block to close 
/// a container tag. 
/// </summary> 
public class MvcContainer : IDisposable 
{ 
    protected bool Disposed { get; set; } 
    protected HttpResponseBase HttpResponse { get; set; } 
    protected string Tag { get; set; } 

    public MvcContainer(HttpResponseBase httpResponse, string tag) 
    { 
     if (httpResponse == null) 
     { 
      throw new ArgumentNullException("httpResponse"); 
     } 

     if (string.IsNullOrEmpty(tag)) 
     { 
      throw new ArgumentNullException("tag"); 
     } 

     this.HttpResponse = httpResponse; 
     this.Tag = tag; 
    } 

    /// <summary> 
    /// Write the closing tag 
    /// </summary> 
    public virtual void EndContainer() 
    { 
     this.Dispose(true); 
    } 

    #region IDisposable Members 

    /// <summary> 
    /// Write the closing tag 
    /// </summary> 
    public void Dispose() 
    { 
     this.Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!this.Disposed) 
     { 
      this.Disposed = true; 
      this.HttpResponse.Write(string.Format("</{0}>", this.Tag)); 
     } 
    } 

    #endregion 
} 
+0

Est-ce que cela permet une visibilité en temps de conception? – Glenn

+0

Non. Vous avez manqué cette partie de votre question. Il est "compatible" avec la vue de conception, mais vous ne pourrez pas voir l'effet puisque le code n'est pas généré avant l'exécution. – tvanfosson

+0

Merci pour le grand détail de votre réponse. Je commence à avoir l'impression que les meilleures pratiques de MVC n'incluent pas l'utilisation de la vue de conception. – Glenn