2010-12-31 3 views
0

donc j'ai un helper html personnalisé que je fais et il rend une table d'un IList qui est passé. Cela fonctionne très bien, mais c'est plutôt basique. J'aimerais avoir la possibilité d'attribuer des noms de colonnes qui ne sont pas déduits du nom de la propriété. Par exemple, en ce moment je passe dans une propriété appelée Numéro, mais je voudrais utiliser .Aide ASP.NET MVC 'RenderTable' personnalisée, comment ajouter des fonctionnalités supplémentaires?

Je pense que je l'ai vu faire à travers des décorations, et je ne peux que supposer qu'il utilise la réflexion pour obtenir la valeur, mais je ne suis pas tout à fait sûr de savoir comment le retirer, mais ...

Une autre chose, je voudrais appliquer la capacité de manipuler les attributs d'une cellule. Par exemple, la cellule doit avoir un colspan de x, ou toute autre cellule peut recevoir un class. Je pense que cela pourrait également tomber sous une décoration quelconque. Enfin, je veux que certaines cellules contiennent des liens, mais franchement, je n'ai aucune idée de comment l'enlever, à moins d'envoyer une chaîne html complète comme valeur de propriété à rendre.

Donc, je poste ma version actuelle du code ici avec l'espoir que quelqu'un de mieux que moi (ce serait vous, ;)) pourrait me donner quelques indications sur la façon d'accomplir ce que j'ai écrit au dessus.

MISE À JOUR

Petite mise à jour, le IList étant passé en droit est maintenant un type anonyme, donc je ne sais pas comment qui joue avec des décorations ...

public static class ApplicationExtensions { 
    public static void RenderTable(
     this HtmlHelper HtmlHelper, 
     IList Items) { 
     RenderTable(HtmlHelper, string.Empty, Items, null, false); 
    } 

    public static void RenderTable(
     this HtmlHelper HtmlHelper, 
     IList Items, 
     object Attributes) { 
     RenderTable(HtmlHelper, string.Empty, Items, Attributes, false); 
    } 

    public static void RenderTable(
     this HtmlHelper HtmlHelper, 
     IList Items, 
     IDictionary<string, object> Attributes) { 
     RenderTable(HtmlHelper, string.Empty, Items, Attributes, false); 
    } 

    public static void RenderTable(
     this HtmlHelper HtmlHelper, 
     IList Items, 
     object Attributes, 
     bool RenderTFoot) { 
     RenderTable(HtmlHelper, string.Empty, Items, Attributes.ToDictionary(), RenderTFoot); 
    } 

    public static void RenderTable(
     this HtmlHelper HtmlHelper, 
     IList Items, 
     IDictionary<string, object> Attributes, 
     bool RenderTFoot) { 
     RenderTable(HtmlHelper, string.Empty, Items, Attributes, RenderTFoot); 
    } 

    public static void RenderTable(
     this HtmlHelper HtmlHelper, 
     string Caption, 
     IList Items, 
     object Attributes, 
     bool RenderTFoot) { 
     RenderTable(HtmlHelper, Caption, Items, Attributes.ToDictionary(), RenderTFoot); 
    } 

    public static void RenderTable(
     this HtmlHelper HtmlHelper, 
     string Caption, 
     IList Items, 
     IDictionary<string, object> Attributes, 
     bool RenderTFoot) { 
     if ((Items != null) && (Items.Count > 0)) { 
      StringBuilder TableBuilder = (String.IsNullOrEmpty(Caption) ? new StringBuilder() : new StringBuilder().AppendFormat("<caption>{0}</caption>", Caption)); 

      THead(TableBuilder, Items[0].GetType()); 
      TBody(TableBuilder, Items); 

      if (RenderTFoot) { 
       TFoot(TableBuilder, Items[0].GetPropertyCount()); 
      }; 

      TagBuilder TagBuilder = new TagBuilder("table"); 

      TagBuilder.MergeAttributes(Attributes); 
      TagBuilder.InnerHtml = TableBuilder.ToString(); 

      HtmlHelper.ViewContext.HttpContext.Response.Write(TagBuilder.ToString(TagRenderMode.Normal)); 
     }; 
    } 

    private static void THead(
     StringBuilder TableBuilder, 
     Type Item) { 
     TableBuilder.Append("<thead><tr>"); 

     foreach (var Property in Item.GetProperties()) { 
      TableBuilder.AppendFormat("<th>{0}</th>", Property.Name); 
     }; 

     TableBuilder.Append("</tr></thead>"); 
    } 

    private static void TBody(
     StringBuilder TableBuilder, 
     IList Items) { 
     TableBuilder.Append("<tbody>"); 

     foreach (var Item in Items) { 
      PropertyInfo[] Properties = Item.GetType().GetProperties(); 

      TableBuilder.Append("<tr>"); 

      foreach (PropertyInfo Property in Properties) { 
       TableBuilder.AppendFormat("<td>{0}</td>", Property.GetValue(Item, null)); 
      }; 

      TableBuilder.Append("</tr>"); 
     }; 

     TableBuilder.Append("</tbody>"); 
    } 

    private static void TFoot(
     StringBuilder TableBuilder, 
     int Columns) { 
     TableBuilder.AppendFormat("<tfoot><tr><td colspan=\"{0}\"><input type=\"button\" value=\"&#9664;\" /><input type=\"button\" value=\"&#9654;\" /></td></tr></tfoot>", Columns); 
    } 

    private static int GetPropertyCount(
     this object Item) { 
     return Item.GetType().GetProperties().Count(); 
    } 

    private static IDictionary<string, object> ToDictionary(
     this object Object) { 
     return Object.GetType().GetProperties().ToDictionary(
      k => 
       (k.Name), 
      v => 
       (v.GetValue(Object, null))); 
    } 
} 

Et il est utilisé comme ceci:

<% Html.RenderTable(Model) // lowest overload... %> 

Répondre

0

Vous pouvez jeter un oeil à Html.Grid de ASP.NET MVC 3 RC2. Cela devrait être beaucoup plus facile que d'écrire votre propre aide.

+0

Hmm, intéressant, mais il nécessite MVC 3. Je travaille contre MVC 2 et je ne prévois pas de jouer avec MVC 3 jusqu'à ce qu'il soit entièrement libéré. En outre, il semble essayer de prendre soin de beaucoup de choses Ajax, ce que je n'aime pas parce que c'est déjà limiter la * conception de code * que je mettrais en œuvre autrement. Je suppose que je veux juste que le mien soit un rendu générique que je puisse "Ajaxifier" comme je le souhaite. Et enfin, je n'ai jamais construit un HtmlHelper avant, donc je vois cela comme une expérience d'apprentissage agréable. – Gup3rSuR4c

+0

@Alex: MVC 3 propose également un nouveau concept pour les helpers HTML, à savoir les helpers déclaratifs. C'est beaucoup moins encombrant et plus facile à maintenir que les aides basées sur le code disponibles dans les versions précédentes. Alors que le «vieux» style d'aide à l'écriture reste le seul choix pour certains scénarios, je suis passé à des aides déclaratives pour la plupart des autres choses. –

+0

Hmm (encore), comment ça se passe avec la réutilisation du code, à court de copier et de coller l'assistant là où vous en avez besoin? Je veux dire, on dirait que vous générez un helper sur la page, ce qui est bien, mais alors ne seriez-vous pas en train de générer exactement le même helper sur chaque vue à laquelle vous voulez l'utiliser? Cela n'ouvrirait-il pas la porte à des problèmes de cohérence si l'on se trouve être différent d'une façon ou d'une autre? – Gup3rSuR4c

0

« Je ne suis pas sûr de savoir comment qui joue avec des décorations ... »

Il ne fonctionne pas. Vous ne pourrez pas extraire les métadonnées d'un anon.

Questions connexes