我正在处理的当前项目允许将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也没有帮助我进行大量搜索。
答案 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;
}
}