【问题标题】:Creating An HtmlTable Using An ASP.NET Repeater Dynamically Bound to an Object List使用动态绑定到对象列表的 ASP.NET 中继器创建 HtmlTable
【发布时间】:2012-06-19 22:48:45
【问题描述】:

我正在以编程方式在转发器内创建一个表。我的问题是项目模板部分中的单元格无法正确呈现。它们在表格标记之后显示为文本节点。有人对如何正确渲染表格单元格有任何建议吗?

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

【问题讨论】:

    标签: c# asp.net webforms


    【解决方案1】:

    这是因为在您的逻辑中,您在 AddHeader 方法中创建一个带有标题的表并将其添加到转发器,这将创建:

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

    然后将列表项添加到转发器,是的转发器,而不是第一个表。 您在表格之后将表格行添加到转发器,浏览器会将这些行和单元格呈现为文本节点,因为它们没有父 tbody 表格元素。

    中继器编写 HTML,因此您需要找到一种方法来拥有打开和关闭表标签

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

    所以中继器渲染将类似于: 雷克斯罗素梗 对于每个项目

    我相信你的逻辑是错误的,如果你希望转发器中的每个项目都作为一个表,你需要像这样更改你的代码:

        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。 如果您希望每个转发器项目成为表的行,则逻辑必须不同。

    【讨论】:

    • 感谢您指出这一点。如果您想查看最终解决方案,我更新了我的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多