从UserControls访问UserControls而不必依赖FindControl

时间:2009-10-28 00:19:07

标签: c# .net asp.net user-controls

我正在处理的当前项目允许将UserControls动态地添加到许多不同占位符的页面中,这些占位符可以是无限数量的模板。所以基本上使用CMS。

很棒我听到你说但是当我想让其中两个UserControl相互通话时会发生什么?即搜索表单控件和搜索结果控件。这是我最近解决的问题,并提出了一个我很满意的解决方案,但我想我会把它漂浮在那里,看看你们都在想什么。

首先,我很快就决定忽略FindControl方法,任何我能想到的解决它的解决方案都变得混乱,让我死了一点。

编辑:不使用FindControl的决定是因为它只搜索Control的子控件集合,因此需要通过控件循环来找到我想要的那个。

这是我到目前为止所做的: 在我的基页类中添加了一个名为BasePage的全局公共属性:

public SortedList<string, CustomUserControl> CustomControls { get; set; }

在我的基本用户控件类中添加了一个名为CustomUserControl的公共属性:

protected SortedList<string, CustomUserControl> CustomControls
{
    get 
    {
        BasePage page = Page as BasePage;
        if (page != null)
            return page.CustomControls;
        else
            return null;
    }
}

在我的UserControls的Page_Init上添加了对CustomControl集合的控件的引用,该集合将它分配给BasePage的属性。

然后我可以使用CustomControl方法从Page或控件本身访问我的UserControls,如下所示:

if (this.CustomControls.ContainsKey("SearchForm"))
    searchForm = this.CustomControls["SearchForm"] as SearchForm;

这就是它的基础知识,我正在改进它,所以请随意选择它。如果你们中的任何人有更好/替代的解决方案,我很乐意听到它。或者即使您已经阅读了有关此问题的文章,Google也没有帮助我进行大量搜索。

2 个答案:

答案 0 :(得分:0)

我不明白你不愿意使用FindControl。想想Microsoft如何解决这个完全相同的问题...具体来说,验证器控制。它们只有一个名为ControlToValidate的属性,它将另一个控件的ID作为字符串。在内部,它可能只是使用FindControl。 (好吧,老实说,我不知道,但似乎有可能打赌)

您的解决方案似乎有点多余,因为Page对象已经包含了所有控件的集合。它只适用于您的特定环境。

编辑:BTW,我只看了内置验证器,他们确实只是使用FindControl。也许我误解了你的要求。

答案 1 :(得分:0)

正如你所说,FindControl只查看容器的直接子项,因此你必须遍历它们才能找到一个控件。为什么这是个问题?如果你使函数递归,整个事情最终只是少数几行代码。如果您将其作为Control类的扩展,则可以方便地访问该函数。

例如:


    public static class ControlExtensions
    {
        public static Control FindControl(this Control control, string id, bool Recursive)
        {
            var result = control.FindControl(id);
            if (!Recursive) return result;
            if (result == null)
            {
                foreach (Control child in control.Controls)
                {
                    result = child.FindControl(id, true);
                    if (result != null) return result;
                }
            }
            return null;
        }
    }