2009-12-11 11 views
6

Sto cercando di creare un'estensione tabella HtmlHelper specifica per ridurre il codice spaghetti nella mia vista.Come creare la tabella MVC HtmlHelper dall'elenco degli oggetti

Prendere un elenco di oggetti di dominio Vorrei visualizzare una tabella che è un po 'più intelligente nell'uso delle proprietà dell'oggetto dominio come colonne. Inoltre, vorrei disabilitare la visualizzazione di alcune proprietà come colonne. Un'idea sarebbe quella di decorare le proprietà con attributi che dicono di non essere mostrate.

Speriamo che abbia un senso, ma qui è dove ho avuto modo finora ...

public static string MyTable(this HtmlHelper helper, string name, 
    IList<MyObject> items, object tableAttributes) 
{ 
    if (items == null || items.Count == 0) 
     return String.Empty; 

    StringBuilder sb = new StringBuilder(); 
    BuildTableHeader(sb, items[0].GetType()); 

    //TODO: to be implemented... 
    //foreach (var i in items) 
    // BuildMyObjectTableRow(sb, i); 

    TagBuilder builder = new TagBuilder("table"); 
    builder.MergeAttributes(new RouteValueDictionary(tableAttributes)); 
    builder.MergeAttribute("name", name); 
    builder.InnerHtml = sb.ToString(); 

    return builder.ToString(TagRenderMode.Normal); 
} 

private static void BuildTableHeader(StringBuilder sb, Type p) 
{ 
    sb.AppendLine("<tr>"); 

    //some how here determine if this property should be shown or not 
    //this could possibly come from an attribute defined on the property   
    foreach (var property in p.GetProperties()) 
     sb.AppendFormat("<th>{0}</th>", property.Name); 

    sb.AppendLine("</tr>"); 
} 

//would be nice to do something like this below to determine what 
//should be shown in the table 
[TableBind(Include="Property1,Property2,Property3")] 
public partial class MyObject 
{ 
    ...properties are defined as Linq2Sql 
} 

Quindi mi stavo chiedendo se qualcuno avesse qualche opinioni/suggerimenti su questo o qualsiasi idea alternative?

risposta

1

Dopo circa un'ora di lavoro sono riuscito a creare ciò che volevo. La mia soluzione era creare un attributo sulla classe dell'oggetto dominio che specificasse quali proprietà erano visibili nella mia tabella.

In base all'attributo BindAttribute in MVC 1.0 (esaminando il codice sorgente), ho creato un attributo TableProperty.

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] 
public class TableProperty : Attribute 
{ 
    private string m_include; 
    private string[] m_includeSplit; 

    public TableProperty() 
    { 
     m_includeSplit = new string[0]; 
    } 

    public string Include 
    { 
     get 
     { 
      return (m_include ?? string.Empty); 
     } 
     set 
     { 
      m_include = value; 
      m_includeSplit = value.Split(','); 
     } 
    } 

    public bool IsPropertyAllowed(string propertyName) 
    { 
     return IsPropertyAllowed(propertyName, m_includeSplit); 
    } 

    internal static bool IsPropertyAllowed(string propertyName, string[] includeProperties) 
    { 
     return ((includeProperties == null) || (includeProperties.Length == 0)) || includeProperties.Contains<string>(propertyName, StringComparer.OrdinalIgnoreCase); 
    } 
} 

Questo mi ha permesso di decorare il mio oggetto dominio con questo attributo ...

[TableProperty(Include="Property1,Property2,Property3")] 
public partial class MyObject 
{ ... 

Poi all'interno del BuildTableHeader ho usato riflessione per ottenere le proprietà dell'oggetto e abbinare ogni alloggio ai Preferiti consentito .

private static void BuildTableHeader(StringBuilder sb, Type p) 
{ 
    sb.AppendLine("<tr>"); 

    TableProperty tp = p.GetCustomAttributes(typeof(TableProperty), true)[0]; 

    foreach (var property in p.GetProperties()) 
     if (tp.IsPropertyAllowed(property.Name)) 
      sb.AppendFormat("<th>{0}</th>", property.Name); 

Si prega di notare che questa soluzione ha funzionato per me nella mia piccola applicazione saranno comunque guardando più a Griglia di MvcContrib per una migliore attuazione.

+0

Considerate anche jqGrid se avete bisogno di flessibilità sul lato client. – queen3

1

vi consiglio caldamente di utilizzare MvcContrib di Grid. Se decidi di non farlo, almeno puoi dare un'occhiata a come hanno risolto il problema dell'interfaccia di generazione della tabella.

+0

Grazie per il collegamento alla griglia. Darò un'occhiata a questo, ma per il momento sono riuscito a implementarlo da solo. – David

Problemi correlati