2009-12-11 21 views
6

Ich versuche, eine bestimmte HtmlHelper-Erweiterung zu erstellen, um den Spaghetti-Code in meiner Ansicht zu reduzieren.Erstellen MVC HtmlHelper Tabelle aus der Liste der Objekte

Eine Liste von Domänenobjekten aufnehmen Ich möchte eine Tabelle anzeigen, die ein wenig intelligenter ist, wenn die Eigenschaften des Domänenobjekts als Spalten verwendet werden. Außerdem möchte ich das Anzeigen einiger Eigenschaften als Spalten deaktivieren. Eine Idee wäre, Eigenschaften mit Attributen zu versehen, die angeben, dass sie nicht angezeigt werden sollen.

Hoffentlich, die Sinn macht, aber hier ist, wo ich so weit gekommen ...

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 
} 

So war ich nur fragen, ob jemand hatte irgendwelche Meinungen/Vorschläge zu dieser Idee oder Alternativen?

Antwort

1

Nach etwa einer Stunde Arbeit konnte ich schaffen, was ich wollte. Meine Lösung bestand darin, eine Attribution für die Domänenobjektklasse zu erstellen, in der angegeben wurde, welche Eigenschaften in meiner Tabelle sichtbar waren.

Basierend auf dem Attribut BindAttribute in MVC 1.0 (mit Blick auf den Quellcode), erstellte ich ein TableProperty-Attribut.

[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); 
    } 
} 

Das erlaubte mir meine Domain-Objekt mit diesem Attribut zu dekorieren ...

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

Dann in der BuildTableHeader verwendete ich Reflektion, um die Eigenschaften des Objekts zu erhalten und jede Eigenschaft der zulässigen Liste übereinstimmen .

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); 

Bitte beachten Sie, diese Lösung arbeitete für mich in meiner kleinen Anwendung, wird jedoch mehr auf MvcContrib Grid für eine bessere Implementierung.

+0

Beachten Sie auch jqGrid, wenn Sie clientseitige Flexibilität benötigen. – queen3

1

Ich empfehle MvcContrib der Grid zu verwenden. Wenn Sie sich entscheiden, nicht, können Sie zumindest einen Blick darauf werfen, wie sie das Problem der Tabellengenerierungsschnittstelle gelöst haben.

+0

Danke für den Link zum Grid. Ich schaue mir das an, konnte es aber vorerst selbst umsetzen. – David