2011-06-26 5 views
0

J'essaie de trouver un modèle léger pour générer une table pour représenter une liste d'objets du modèle et afficher les champs spécifiés en colonnes. Jusqu'à présent, c'est ce que j'ai trouvé, avec quelques problèmes ennuyeux.Afficher facilement des données tabulées?

DataTable.cs:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Linq; 

namespace Models 
{ 
    public interface IDataTable 
    { 
     List<string> ColumnNames { get; } 

     List<List<string>> TableRows { get; } 
    } 

    public class DataTable<T> : IDataTable 
    { 
     private Type TableType = typeof(T); 

     public List<string> Columns { get; set; } 

     public List<T> RowData { get; set; } 

     public List<string> ColumnNames 
     { 
      get 
      { 
       List<string> columnNames = new List<string>(); 
       foreach (string colPropName in Columns) 
        columnNames.Add(GetPropertyDisplayName(colPropName)); 
       return columnNames; 
      } 
     } 

     public List<List<string>> TableRows 
     { 
      get 
      { 
       List<List<string>> tableRows = new List<List<string>>(); 
       foreach (T rowObj in RowData) 
       { 
        List<string> tableRow = new List<string>(); 
        foreach (string propName in Columns) 
        { 
         object value = TableType.GetProperty(propName).GetValue(rowObj, null); 
         if (value != null && value != String.Empty) 
          tableRow.Add(value.ToString()); 
         else 
          tableRow.Add("N/A"); 
        } 
        tableRows.Add(tableRow); 
       } 
       return tableRows; 
      } 
     } 

     public DataTable(List<string> columns, List<T> rowData) 
     { 
      Columns = columns; 
      RowData = rowData; 
     } 

     private string GetPropertyDisplayName(string propName) 
     { 
      DisplayNameAttribute attrib = TableType.GetProperty(propName).GetCustomAttributes(true).OfType<DisplayNameAttribute>().FirstOrDefault(); 
      if (attrib != null) 
       return attrib.DisplayName; 
      return propName; 
     } 
    } 
} 

Commun/DataTable.cshtml:

@model IDataTable 

<table class="rounded-corner-table" summary="2007 Major IT Companies' Profit"> 
    <thead> 
     <tr> 
      @foreach (string colName in Model.ColumnNames) 
      { 
       <th scope="col">@colName</th> 
      } 
     </tr> 
    </thead> 
     <tfoot> 
     <tr> 
      <td colspan="@(Model.ColumnNames.Count - 1)" class="rounded-foot-left"><em>To be implemented: Instant search.</em></td> 
      <td class="rounded-foot-right">&nbsp;</td> 
     </tr> 
    </tfoot> 
    <tbody> 
     @for (int i = 0; i < Model.TableRows.Count; ++i) 
     { 
      <tr> 
       @foreach (string colValue in Model.TableRows[i]) 
       { 
        <td>@colValue</td> 
       } 
      </tr> 
     } 
    </tbody> 
</table> 

Comment puis-je les utiliser:

public ActionResult List() 
     { 
      return PartialView(new DataTable<Administrator>(new List<string> { "EmailAddress", 
       "FirstName", 
       "LastName", 
       "Date" }, 
       Root.DataContext.Administrators.ToList())); 
     } 
//_______________________________________________________________________________ 
@model DataTable<Administrator> 

@{Html.RenderPartial("DataTable");} 

Les deux principaux problèmes que je suis avec c'est rencontrais Je préférerais être en mesure d'appeler Html.DisplayForModel() mais je ne sais pas comment le faire fonctionner et qu'il ne montre pas le Attributs DisplayName pour les noms de colonne dans la table. Quelqu'un peut-il me donner quelques conseils sur ces questions?

Merci, Alex.

MISE À JOUR - Correction ma deuxième question:

private string GetPropertyDisplayName(string propName) 
     { 
      DisplayNameAttribute attrib = TableType.GetProperty(propName).GetCustomAttributes(true).OfType<DisplayNameAttribute>().FirstOrDefault(); 
      if (attrib == null) 
      { 
       MetadataTypeAttribute metaAttrib = TableType.GetCustomAttributes(true).OfType<MetadataTypeAttribute>().FirstOrDefault(); 
       if (metaAttrib != null) 
        attrib = metaAttrib.MetadataClassType.GetProperty(propName).GetCustomAttributes(true).OfType<DisplayNameAttribute>().FirstOrDefault(); 
      } 

      if (attrib != null) 
       return attrib.DisplayName; 

      return propName; 
     } 
+0

Je trouve essayer de généraliser des trucs comme ça est un puits sans fond - il suffit d'écrire le code pour chaque table applicable - il va vous faire économiser du temps et de l'agro. – iwayneo

Répondre

0

Je pense que vous êtes à peu près là. Ça a l'air plutôt bien.

Qu'en est-il de la configuration d'un modèle d'affichage tabulaire, selon le blog de Phil Haack here?

Ensuite, vous pouvez l'appeler comme ça Html.DisplayForModel("TableTemplateName")

Questions connexes