2012-06-19 65 views
2

我在編程中通過中繼器創建表。我的問題是,項目模板部分中的單元格無法正確呈現。它們在表格標記後顯示爲文本節點。有沒有人有關於如何正確獲取表格單元格的建議?使用ASP.NET中繼器創建HtmlTable動態綁定到對象列表

using System; 
using System.Collections.Generic; 
using System.Web.UI; 
using System.Web.UI.HtmlControls; 
using System.Web.UI.WebControls; 

namespace WebApplication1 
{ 
    public partial class WebForm2 : Page 
    { 
     protected void Page_Load(object sender, EventArgs e) 
     { 
      if (!IsPostBack) 
      { 
       var dogs = new List<Dog> 
       { 
        new Dog { Name = "Rex", Breed = "Russell Terrier" }, 
        new Dog { Name = "Fido", Breed = "Poodle" }, 
        new Dog { Name = "Fetcher", Breed = "Golden Retriever" }, 
       }; 

       var repeater = new Repeater { ID = "Repeater1" }; 
       repeater.DataSource = dogs; 
       repeater.DataBind(); 

       AddHeader(repeater); 
       AddItems(repeater, dogs); 

       PlaceHolder1.Controls.Add(repeater); 
      } 
     } 

     private void AddHeader(Repeater repeater) 
     { 
      var repeaterItem = new RepeaterItem(0, ListItemType.Header); 
      var table = new HtmlTable(); 
      var row = new HtmlTableRow(); 
      var cell1 = new HtmlTableCell("th") { InnerText = "Name" }; 
      var cell2 = new HtmlTableCell("th") { InnerText = "Breed" }; 
      row.Cells.Add(cell1); 
      row.Cells.Add(cell2); 
      table.Rows.Add(row); 
      repeaterItem.Controls.Add(table); 
      repeater.Controls.Add(repeaterItem); 
     } 

     private void AddItems(Repeater repeater, List<Dog> dogs) 
     { 
      for (var i = 0; i < repeater.Items.Count; i++) 
      { 
       var repeaterItem = new RepeaterItem(i + 1, ListItemType.Item); 
       var row = new HtmlTableRow(); 
       var cell1 = new HtmlTableCell() { InnerText = dogs[i].Name }; 
       var cell2 = new HtmlTableCell() { InnerText = dogs[i].Breed }; 
       row.Cells.Add(cell1); 
       row.Cells.Add(cell2); 
       repeaterItem.Controls.Add(row); 
       repeater.Controls.Add(repeaterItem); 
      } 
     } 

     private sealed class Dog 
     { 
      public string Breed { get; set; } 
      public string Name { get; set; } 
     } 
    } 
} 

更新:感謝Rob的幫助,我能夠得到代碼的工作。現在我有一個全功能的Repeater被完全加載到代碼隱藏的數據綁定中。太好了!

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web.UI; 
using System.Web.UI.HtmlControls; 
using System.Web.UI.WebControls; 
using ExtensionMethods.WebControls; 

namespace WebApplication1 
{ 
    public partial class WebForm1 : Page 
    { 
     protected void Page_Load(object sender, EventArgs e) 
     { 
      var dogs = new List<Dog> 
      { 
       new Dog { Name = "Rex", Breed = "Russell Terrier" }, 
       new Dog { Name = "Fido", Breed = "Poodle" }, 
       new Dog { Name = "Fetcher", Breed = "Golden Retriever" }, 
      }; 

      var repeater = new Repeater 
      { 
       ID    = "Repeater1", 
       HeaderTemplate = new CustomTemplate(ListItemType.Header), 
       ItemTemplate = new CustomTemplate(ListItemType.Item), 
       FooterTemplate = new CustomTemplate(ListItemType.Footer), 
       DataSource  = dogs 
      }; 

      repeater.DataBind(); 
      PlaceHolder1.Controls.Add(repeater); 
     } 

     // Custom template class to add controls to the repeater's header, item and footer sections. 
     private sealed class CustomTemplate : ITemplate 
     { 
      private ListItemType ListItemType { get; set; } 

      public CustomTemplate(ListItemType type) 
      { 
       ListItemType = type; 
      } 

      public void InstantiateIn(Control container) 
      { 
       if (ListItemType == ListItemType.Header) 
       { 
        var table = new LiteralControl(); 
        var head = new HtmlGenericControl("thead"); 
        var row = new HtmlTableRow(); 
        row.Cells.Add(new HtmlTableCell("th") { InnerText = "Breed" }); 
        row.Cells.Add(new HtmlTableCell("th") { InnerText = "Name" }); 
        head.Controls.Add(row); 
        table.Text = string.Format("<table>{0}<tbody>", head.RenderHtml()); 
        container.Controls.Add(table); 
       } 
       else if (ListItemType == ListItemType.Item) 
       { 
        var row = new HtmlTableRow(); 

        var cell1 = new HtmlTableCell(); 
        cell1.Controls.Add(new Literal { ID = "LiteralBreed" }); 
        row.Cells.Add(cell1); 

        var cell2 = new HtmlTableCell(); 
        cell2.Controls.Add(new Literal { ID = "LiteralName" }); 
        row.Cells.Add(cell2); 

        container.Controls.Add(row); 
        container.DataBinding += new EventHandler(Container_DataBinding); 
       } 
       else if (ListItemType == ListItemType.Footer) 
       { 
        var footer = new LiteralControl("</tbody></table>"); 
        container.Controls.Add(footer); 
       } 
      } 

      // Event handler to populate the dog's breed and name in the table when data-binding occurs. 
      private void Container_DataBinding(object sender, EventArgs e) 
      { 
       var item = sender as RepeaterItem; 
       if (item != null) 
       { 
        var dog = ((Dog)item.DataItem); 

        var breed = item.FindDescendantsByType<Literal>().Single(x => x.ID == "LiteralBreed"); 
        breed.Text = dog.Breed; 

        var name = item.FindDescendantsByType<Literal>().Single(x => x.ID == "LiteralName"); 
        name.Text = dog.Name; 
       } 
      } 
     } 

     private sealed class Dog 
     { 
      public string Breed { get; set; } 
      public string Name { get; set; } 
     } 
    } 
} 

回答

3

那是因爲你的邏輯,你要創建一個表中的AddHeader方法的頭並將其添加到中繼器,將創建:

<table> 
<tbody><tr> 
    <th>Name</th> 
    <th>Breed</th> 
</tr></tbody> 
</table> 

然後添加列表項到中繼器,是轉發器,不是第一張表。 您正在將錶行添加到表格之後的重複器中,並且瀏覽器會將這些行和單元格渲染爲文本節點,因爲它們沒有父級tbody表格元素。

中繼器,所以你需要找到一種方法,有打開和關閉表標籤

<table> 
    <tbody> 
     <asp:Repeater ID="fooRepeater" runat="server" ></asp:Repeater> 
    </tbody>  
</table> 

寫入HTML這樣的中繼器渲染會是這樣的: RexRussell梗 對於每個項目

我相信你的邏輯是錯誤的,如果你想在直放站的每個項目作爲一個表,你需要改變你的代碼是這樣的:

private void AddItems(Repeater repeater, List<Dog> dogs) 
    { 
     var repeaterItem = new RepeaterItem(0, ListItemType.Header); 
     var table = new HtmlTable(); 
     var row = new HtmlTableRow(); 
     var cell1 = new HtmlTableCell("th") { InnerText = "Name" }; 
     var cell2 = new HtmlTableCell("th") { InnerText = "Breed" }; 
     row.Cells.Add(cell1); 
     row.Cells.Add(cell2); 
     table.Rows.Add(row); 

     for (var i = 0; i < repeater.Items.Count; i++) 
     { 
      repeaterItem = new RepeaterItem(i + 1, ListItemType.Item); 
      row = new HtmlTableRow(); 
      cell1 = new HtmlTableCell() { InnerText = dogs[i].Name }; 
      cell2 = new HtmlTableCell() { InnerText = dogs[i].Breed }; 
      row.Cells.Add(cell1); 
      row.Cells.Add(cell2); 

      table.Rows.Add(row); 
     } 

     repeaterItem.Controls.Add(table); 
     repeater.Controls.Add(repeaterItem); 

    } 

所有事情都會發生在AddItems方法中,並且不再需要AddHeader。 如果您希望每個中繼器項目是表格的行,則邏輯必須不同。

+1

謝謝你指出。如果您想查看最終解決方案,我更新了代碼。 – Halcyon

+0

請更新代碼... for(var i = 0; i Madhu

相關問題