访问UserControl的模板项

时间:2014-02-07 18:30:27

标签: c# asp.net user-controls

是否可以实现自定义UserControlControl,它将像PlaceHolder一样,但我的逻辑?使用示例:

<x:MyControl runat="server">
    <Template>
        <asp:TextBox runat="server" ID="MyTextBox" />
        ..... any custom code here ........
    </Template>
</x:MyControl>

然后在代码隐藏中:

MyTextBox.Text = "ABC";

我实现了测试控件,但是我无法访问页面级别的嵌套ASP控件。错误是The name "MyTextBox" does not exist in the current context

2 个答案:

答案 0 :(得分:1)

您必须在用户控件MyControl中调用“FindControl”功能。 将您的MyControl命名为id="mcContainer",然后将您的代码命名为((TextBox)mcContainer.FindControl("MyTextBox")).Text = "ABC";

维基关于此How to: Create Templated ASP.NET User Controls

为什么我可以在页面中写MyTextBox.Text="ABC",当文本框在用户控件实现的命名容器内时,为什么不可能呢?

好吧,当您拖动N删除文本框时,ASP.NET页面设计器在为设计者自己保留的页面的部分类中为您声明了一个变量,在您的类的设计器部分中,您的控件在您中页面已声明。

因此,当您拖放用户控件并在其命名容器内创建文本框时,您无法直接访问它,因为您的页面没有对该控件的引用,原因是因为控件只能在用户控件本身的实例化过程中在运行时使用,动机部分与ASP.NET页面解析器呈现控件的方式有关。

引用此resource: 使用复合控件时,熟悉许多属性和方法以及INamingContainer接口非常重要。所有复合控件都应实现INamingContainer接口。实现此接口的控件不需要添加任何方法或属性;相反,实现的接口仅表示该控件正被用作复合控件。结果是子控件(即复合控件的Controls集合中的控件)被渲染,以便它们的ID以控件命名容器的ID为前缀。这可确保所有子控件都具有唯一的ID值,即使Form上有多个父控件实例也是如此。 WebControl类有一个NamingContainer属性,它返回控件的父级。

因此,当你编写MyTextBox时,你的文本框名称至少应该是$ mcContainer $ MyTextBox。因此,没有办法透明地做你想要的。

答案 1 :(得分:0)

解。

像这样创建类:

public class ToolTip : PlaceHolder
{
    protected override void CreateChildControls()
    {
        HtmlGenericControl div1 = new HtmlGenericControl("div");
        div1.Attributes.Add("id", ClientID);
        div1.Attributes.Add("class", "tooltip");
        while (Controls.Count != 0)
            div1.Controls.Add(Controls[0]);
        Controls.Add(div1);
    }
}

然后在ASPX文件中注册,如下所示:

<%@ Register Assembly="YOUR_ASSEMBLY" TagPrefix="x" Namespace="YOUR_NAMESPACE" %>

然后像这样使用它:

<x:ToolTip runat="server">
    ... any your content here ......
</x:ToolTip>

现在,您可以在x:ToolTip内嵌套任何控件,并将任何合成逻辑添加到CreateChildControls()