如何用asp.net中的代码包装一个带有div的控件?

时间:2014-12-20 09:24:43

标签: c# html asp.net vb.net

是否可以添加一个可以从后面包装控件的div标签?我想向我的函数发送一个控件列表,并让它动态地在每个控件周围添加一个div,这样每个控件都在它自己的div中。

实施例: HTML:

...
<p> some text</p>
Name: <asp:textbox id="txtName" runat="server" />
...

函数应该可以使标记看起来像这样 -

...
<p> some text</p>
Name: <div id="divName" runat="server"><asp:textbox id="txtName" runat="server" /></div>
...

1 个答案:

答案 0 :(得分:2)

是的,并且有多种方法可以做到这一点。

推荐的解决方案:创建自定义控件

您可以轻松创建扩展System.Web.UI.WebControls.TextBox的自定义控件,并覆盖Render方法为您编写标记。这为您提供了控件呈现方式的最大灵活性。此示例使用base.Render()呈现TextBox本身,但通过直接写入DIV将其包含在HtmlTextWriter中。这样做的主要好处是,您可以在后面的代码中使用自定义控件,就像任何其他服务器控件一样,您可以在.aspx / .ascx文件中声明它。

即便:

public class WrappedTextBox : System.Web.UI.WebControls.TextBox
{
    protected override void Render(HtmlTextWriter writer)
    {
        writer.Write("<div id=\"div{0}\" runat=\"server\">", this.ID.Replace("txt", String.Empty));
        base.Render(writer);
        writer.WriteEndTag("div");
    }
}

要在ASPX页面中使用该控件,首先要Register控件的命名空间:

<%@ Register Assembly="WebApplication1" TagPrefix="cc" Namespace="WebApplication1" %>

然后将控件添加到表单中,如下所示:

<cc:WrappedTextBox ID="txtName" runat="server" Text="Wrapped!" />

cc只是我选择的任意前缀,但你可以自己编造! (cc用于&#34;自定义控件&#34;)

请注意,在runat=\"server\"输出中可能不需要div(尽管您可能正在编写生成ASPX内容的代码,我想)。 runat="server"只是告诉ASP.NET您希望它是服务器控件,但在这种情况下,您的WrappedTextBox是服务器控件。另请注意,这不一定是最佳做法示例。我不会正常替换txt,而是使用div ID的自定义属性。 (但是这个例子将给出请求的输出。)

替代解决方案:深度优先搜索和修改控制树

    protected void Page_Load(object sender, EventArgs e)
    {
        DeepControlSearch(Page);
    }
    private void DeepControlSearch(Control control)
    {
        if (control.HasControls())
        {
            for (int c = control.Controls.Count - 1; c > -1; c--)
            {
                DeepControlSearch(control.Controls[c]);
            }
        }
        if (control is TextBox)
        {
            WrapTextBox((TextBox)control);
        }
    }
    private void WrapTextBox(TextBox textBox)
    {
        System.Web.UI.HtmlControls.HtmlGenericControl div = new System.Web.UI.HtmlControls.HtmlGenericControl("div");
        div.ID = String.Format("div{0}", textBox.ID.Replace("txt", String.Empty));
        div.Attributes["runat"] = "server";
        Control parent = textBox.Parent;
        parent.Controls.Remove(textBox);
        div.Controls.Add(textBox);
        parent.Controls.Add(div);
    }

这种方法的好处是您不必创建自定义控件(这需要一些前期工作,但通常是值得的投资,因为您可以在任何ASP.NET项目中重用它们) 。 HtmlGenericControl可以像任何其他服务器控件一样进行操作,但它是动态的,因此如果要在ViewState上访问它,则需要在PostBack中(除非您想要这样做) oldskool方法并循环遍历已发布的Form元素以从动态控件中获取值。)

不确定我会推荐第二种方法;这实际上是为自定义控件制作的。

替代解决方案#2:发出JavaScript(jQuery让它变得非常简单)来包装控件

您可以使用ClientScript.RegisterStartupScript()发出一些JavaScript或jQuery来执行此操作,例如:

ClientScript.RegisterStartupScript(
    this.GetType(),
    "wrap textboxes",
    "$(document).ready(function(){$('input:text').each(function(){$(this).wrap('<div id=\"div' + this.id.replace('txt', '') + '\"></div>');});});",
    true);