1

我正在玩从 System.Web.UI.WebControls.Table/Cell/Row 派生并且无法让 HtmlTextWriter.AddAttribute 工作:

桌子:

public class Table : System.Web.UI.WebControls.Table
{
    public string Title { get; set; }
    public bool Sorted { get; set; }

    public Table()
    {
    }
}

表头行:

public class TableHeaderRow : System.Web.UI.WebControls.TableHeaderRow
{
    public TableHeaderRow()
    {
        this.TableSection = TableRowSection.TableHeader;
        this.ClientIDMode = System.Web.UI.ClientIDMode.Static;
    }
}

表头单元格:

public class TableHeaderCell : System.Web.UI.WebControls.TableHeaderCell
{
    public TableHeaderCell()
    {
    }

    public override void RenderBeginTag(HtmlTextWriter writer)
    {
        AddAttributesToRender(writer);
        writer.AddAttribute("test", "whee");
        writer.WriteBeginTag("th");
        //writer.WriteAttribute("test", "whee");
        writer.WriteLine('>');
    }

    public override void RenderEndTag(HtmlTextWriter writer)
    {
        writer.WriteEndTag("th");
        writer.WriteLine();
    }
}

用法:

    <Internal:Table ID="somethingTbl" runat="server" Title="A Table" Sorted="true">
        <Internal:TableHeaderRow>
            <Internal:TableHeaderCell>
                Stuff
            </Internal:TableHeaderCell>
            <Internal:TableHeaderCell>
                More Stuff
            </Internal:TableHeaderCell>
            <Internal:TableHeaderCell>
                Less Stuff
            </Internal:TableHeaderCell>
        </Internal:TableHeaderRow>
    </Internal:Table>

然后在cs中添加一些常规行。我得到以下部分输出:

    <table id="activationsTbl">
<thead>
    <tr>
        <th>

                Stuff
            </th>
        <th>

                More Stuff
            </th>
        <th>

                Less Stuff
            </th>
    </tr>
</thead><tbody test="whee" test="whee" test="whee">
...

正如你所看到的,属性被写在所有 th 标签之后的下一个开始标签(最后的 tbody 标签)。如果我使用注释掉的 WriteAttributes,那么它会被正确写入。如果没有任何其他行(因此没有<tbody>),则属性不会写入任何其他标签。

4

2 回答 2

1

几分钟后,我意识到 WriteBeginTag 和 RenderBeginTag *facepalm* 之间存在差异。

于 2012-10-04T21:50:20.163 回答
1

这是一个自定义控件的示例,它是轻量级的并且是为应用程序量身定制的。它继承自我用于所有项目的基本自定义控件,但它的基类是 System.Web.UI.Control,我建议使用从其他具有开销和代码的 WebControls 过度继承,你看不到,有时可以装箱你呢。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Solution.Data.Portfolio;
using Solution.Web.Data.Portfolio;

namespace Solution.Web.UI.Portfolio
{
    public class ClientIconListControl : UI.Control
    {
        private PortfolioSystem Portfolio { get { return ((iPortfolioControl)Parent).PortfolioSystem; } }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            Page.HeadJQueryOnLoadGeneralRendering += new Deployment.Web.UI.Head.AdditionalRenderingHandler(Page_HeadJQueryOnLoadGeneralRendering);
        }

        void Page_HeadJQueryOnLoadGeneralRendering(System.Web.UI.HtmlTextWriter writer)
        {
            if (this.Visible)
            {
                foreach (KeyValuePair<string, Client> c in this.Portfolio.Clients)
                {
                    writer.WriteLine("gPortfolio.RegisterClientIcon('{2}_{0}_container', {1}, '{0}');", c.Key, c.Value.SpriteIconIndex * 183, this.ClientID);
                }
            }
        }

        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            if (this.Visible)
            {
                string sImageSpacerPath = Page.ResolveUrl("~/ui/image/spacer.gif");
                writer.Indent = 2;
                foreach (KeyValuePair<string, Client> c in this.Portfolio.Clients)
                {
                    if (c.Value.Projects.Count > 0)
                    {
                        writer.WriteLine("<div id=\"{1}_{0}_container\" class=\"icon\">", c.Key, this.ClientID);
                        writer.Indent++;
                        writer.Write("<img id=\"{4}_{3}\" src=\"{0}\" alt=\"{1}\" class=\"{2}\" />", sImageSpacerPath, c.Value.Title, "spwi", c.Key, this.ClientID);
                        writer.WriteLine();
                        writer.WriteLine("<div class=\"hover\">");
                        writer.Indent++;
                        writer.WriteLine("<img src=\"{0}\" alt=\"\" class=\"spwi spwi_overlay\" />", sImageSpacerPath);
                        writer.WriteLine("<h3>{0}</h3><p>{1}</p>", c.Value.Title, String.Empty);
                        writer.Indent--;
                        writer.WriteLine("</div>");
                        writer.Indent--;
                        writer.WriteLine("</div>");
                    }
                }
            }
        }
    }
}

您将不得不忽略一些基于较大项目/解决方案的功能,但只需覆盖 Render 功能,您就可以在此处自定义控件,而不必弄乱 RenderBeginTag 等。

不是您的问题的答案,而是创建控件时要考虑的问题。我花了大约 10 分钟的时间来完成它,如果发生了未计划的更改,我可以完全控制以任何我想要的方式进行更改,而不必在更强大的控制范围内工作。

于 2012-10-08T22:54:03.253 回答