ASP.NET:公开Web用户控件的控件

时间:2009-04-14 02:27:44

标签: asp.net user-controls

我创建了一些Web用户控件(.ascx文件)并将它们放入Pages中。用户控件中有一些TextBox,我希望Page能够直接访问。

将用户控件中的这些TextBox暴露给包含用户控件的Pages的最简单(读取:最少时间)方法是什么?

我知道的两个选项是从Pages调用myUserControl.FindControl(id)(这甚至可以从Page?),并在用户控件中编写属性以显示TextBox值。

似乎都不理想。 FindControl()要求Page知道用户控件中TextBox的ID,从而破坏封装并添加硬编码字符串,并且考虑到这些用户中TextBox的数量,在用户控件中编写一堆属性将非常耗时控件。

无法在我的用户控件中声明这些TextBox是公开的而不是受保护的

5 个答案:

答案 0 :(得分:4)

(撇开关于你所描述的事实与最佳实践完全相反的事实的明显评论......)

如果您使用的是Web应用程序类型项目,则每个UserControl都应该有一个designer.cs文件。它包含每个子控件的声明,因此您可以将访问修饰符更改为public。

如果您使用的是网站类型项目,则应该转换为Web应用程序。 According to Microsoft(并且经验支持),当您计划编写跨越单个代码隐藏的广泛代码时,不应使用网站类型。

答案 1 :(得分:2)

如果我必须这样做,我会写一个暴露控件的公共属性。但是,通常有一种方法可以重写信息,这样您就不需要公开内部控件。如果您需要的只是值,请创建一个返回值的属性。如果您需要客户端ID,则创建公开值或事件的客户端对象可能会解决问题。请记住,一旦你公开,你就会暴露合同,改变合同几乎总是很痛苦。

答案 2 :(得分:1)

您可以将其作为属性从后面的代码公开。你真的只能从代码访问它的属性,而不是从ASP.Net设计师那里访问它的属性。这是vb中的一个示例,它在用户控件上公开DropDownList(并且,它可能不是最佳实践,但它肯定胜过编写代码以公开子控件上的每个属性):

''' <summary>
''' This is the exposed DropDownList for this control.
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property DrowDownList() As DropDownList
    Get
        Return ddControlList
    End Get
End Property

答案 3 :(得分:0)

为什么不让用户控制TextBoxes的集合,将集合公开为属性,在Init()方法中,只需将所有文本框添加到集合中?

这样,你有一个集合,你可以根据需要搜索ID,而不依赖于任何页面逻辑,你只需暴露一个属性。如果您为它创建自己的集合类,您甚至可以使用几种方便的方法来编写以您需要的方式访问文本框。

答案 4 :(得分:0)

从公共基类派生所有Web用户控件,并将此功能公开为公共方法(或方法)。您的基类可以从UserControl派生(通常是.ascx的方式),而您的控件又从它派生。

然后,即使使用反射似乎有点工作,你只需要做一次。如果文本框是动态的,并且您希望避免硬编码,那么这就是您的选择。

因此,如果您需要从父级获取id的文本框值,可以在基类中添加以下内容:

    public string GetTextboxValue(string id)
    {
        string textValue = string.Empty;
        Control ctl = FindControl(id);
        if (ctl.GetType() == typeof(TextBox))
            textValue = ((TextBox)ctl).Text;
        return textValue;
    }

我会说这条路线与之前关于将TextBox公开的建议相比,因为你真的只想从父级读取文本值而不是将整个对象公开为读/写。