2012-11-16 32 views
7

我想創建一個HtmlHelper創建一個HTML表。我希望幫助程序能夠獲取任何類型的對象列表以及要顯示爲列的對象屬性列表。這樣的事情:通用HtmlHelper從任何類型的列表創建HTML表

public static HtmlString Table(this HtmlHelper helper, List<T> data, List<string> headers) 
    { 
     //Tags 
     TagBuilder table = new TagBuilder("table"); 
     TagBuilder tr = new TagBuilder("tr"); 
     TagBuilder td = new TagBuilder("td"); 
     TagBuilder th = new TagBuilder("th"); 

     //Inner html of table 
     StringBuilder sb = new StringBuilder(); 

     //Add headers 
     foreach (var s in headers) 
     { 
      th.InnerHtml = s; 
      tr.InnerHtml += th.ToString(); 
     } 
     sb.Append(tr.ToString()); 

     //Add data 
     foreach (var d in data) 
     { 
      tr.InnerHtml = ""; 
      foreach (var h in headers) 
      { 
       td.InnerHtml = d.h.ToString(); 
       tr.InnerHtml += td.ToString(); 
      } 
      sb.Append(tr.ToString()); 
     } 

     table.InnerHtml = sb.ToString(); 
     return new HtmlString(table.ToString()); 
    } 

這段代碼當然不起作用,但我想知道是否有可能做出類似的東西?我怎麼可能會這樣做。

編輯:

我選擇了以下解決方案,當時的想法是,該表只應包含在標題列表中指定的元素,所以這就是我想出了:

public static HtmlString Table<T>(this HtmlHelper helper, List<T> data, List<string> headers) 
{ 
    //Tags 
    TagBuilder table = new TagBuilder("table"); 
    TagBuilder tr = new TagBuilder("tr"); 
    TagBuilder td = new TagBuilder("td"); 
    TagBuilder th = new TagBuilder("th"); 

    //Inner html of table 
    StringBuilder sb = new StringBuilder(); 

    //Add headers 
    foreach (var s in headers) 
    { 
     th.InnerHtml = s; 
     tr.InnerHtml += th.ToString(); 
    } 
    sb.Append(tr.ToString()); 

    //Add data 
    foreach (var d in data) 
    { 
     tr.InnerHtml = ""; 
     foreach (var h in headers) 
     { 
      td.InnerHtml = d.GetType().GetProperty(h).GetValue(d, null).ToString(); 
      tr.InnerHtml += td.ToString(); 
     } 
     sb.Append(tr.ToString()); 
    } 

    table.InnerHtml = sb.ToString(); 
    return new HtmlString(table.ToString()); 
} 
+0

如果我假設你的'List ''T'通過'public properties'映射到頭部,你會感覺舒服嗎? – LukeHennerley

+0

這個想法是,一個標題對應於T的一個公共屬性。所以我想答案是肯定的。 – Marius

回答

8
public HtmlTable BuildTable<T>(List<T> Data) 
{ 
    HtmlTable ht = new HtmlTable(); 
    //Get the columns 
    HtmlTableRow htColumnsRow = new HtmlTableRow(); 
    typeof(T).GetProperties().Select(prop => 
             { 
              HtmlTableCell htCell = new HtmlTableCell(); 
              htCell.InnerText = prop.Name; 
              return htCell; 
             }).ToList().ForEach(cell => htColumnsRow.Cells.Add(cell)); 
    ht.Rows.Add(htColumnsRow); 
    //Get the remaining rows 
    Data.ForEach(delegate(T obj) 
    { 
    HtmlTableRow htRow = new HtmlTableRow(); 
    obj.GetType().GetProperties().ToList().ForEach(delegate(PropertyInfo prop) 
    { 
     HtmlTableCell htCell = new HtmlTableCell(); 
     htCell.InnerText = prop.GetValue(obj, null).ToString(); 
     htRow.Cells.Add(htCell); 
    }); 
    ht.Rows.Add(htRow); 
    }); 
    return ht; 
} 

試試看。您需要撥打BuildTable<YourType>(list)

+0

不完全是我正在尋找,但足夠接近。它讓我走上了正軌。查看我編輯的最終解決方案。 – Marius

+0

@Maris上面的代碼肯定是更高效/更充分?你只需要在上面的代碼中傳遞一個方法列表,並且它實現了同樣的事情嗎?只要它幫助你找到你需要去的地方,那就很酷:) – LukeHennerley

+0

@Marius我發現你只想要特定的標題,這在開始時並不清楚,我以爲你想要所有的屬性。如果你想要我重構這個來做到這一點,我會嗎? – LukeHennerley