嵌套用户控件 - 如何最好地获取对祖先控件的引用

时间:2009-01-15 01:01:48

标签: .net user-controls nested

我意识到很多代码都不适合这里,但我要求大方向或指针。

我有一个.NET用户控件嵌套六个深度,用于交互式小工具:(外部到内部):包装器,标签,面板,列表,行,项目。

我试图从嵌套控件中获取对祖先控件的引用。

具体来说,我在嵌入式“伟大的大孩子”控件的代码背后有这段代码。它有效,但非常难看:

MyTab _myTab = this.Parent.Parent.Parent.Parent.FindControl(thisTab) as MyTab;

等于{ASP.controls_appname_widget_mywidget_mytab_ascx}并且是正确的。

我意识到我可以做类似的事情 Page.FindControl(“MyWrapper:MyPanel:etc .....”)但也不建议这样做,因为结构或ID可以改变....

有没有合适的选择?

5 个答案:

答案 0 :(得分:2)

请记住,组件最好是无知的。您永远不希望任何控件对层次结构中的任何内容有任何了解,并且在层次结构中仅具有控件下方的控件知识。从长远来看,这种架构方法可以为您节省许多痛苦和痛苦,并且可以避免像您现在这样的情况。

至于修复当前问题,修复它的最佳方法是在控件中创建一个可由父控件设置的MyTab成员。这不是一个完美的解决方案,因为你的控制并不完全不知道其他人,但至少你不再需要知道如何获得MyTab参考 - 它将提供给你。

因此,我将创建一个名为ParentTab之类的属性,并将此属性设置为等于页面中某处的MyTab引用或控件中的内容,该控件可以同时显示MyTab和你的控制。

答案 1 :(得分:0)

我认为这实际上取决于您对控件的使用。如果控件只服务于一个业务需求并且仅在一个页面上用于满足用例,那么就不需要对接口和属性感到疯狂。我没有看到parent.parent.parent.etc的想法有什么问题;我自己多次使用它。我会将它包装在一个属性中,这样无论何时你需要它你都可以调用this.MyGreatGreatGrandFatherProperty。它将更具可读性,如果您的层次结构深度发生变化,您只有一个地方需要修复。

现在,如果它是一个通用组件,你不能控制许多用例的使用,或者在很多用例中需要它,那么你需要为父级添加属性来告诉你他们要保持解耦。

答案 2 :(得分:0)

@Andrew,不是为了劫持我自己的线程而是为了澄清和讨论一种设计方法。你已经说过“你永远不希望任何控制对层次结构中的任何事物都有任何了解......”这显然是一个伟大的设计策略。但是内置了某种集中式管理的包装容器的情况又如何呢?例如,在.NET中,嵌套母版页中的ScriptManager控件。您只需要创建一次脚本管理器,并且您希望它可用于应用程序中的各种控件。例如,应用程序中任何嵌入式控件中的任何UpdatePanel都希望知道该ScriptManager的存在。这是一种错误的做法吗?

我的设计类似 - 最外层的包装容器管理对象持久性,每个控件都可以将其状态保存到该Manager。我现在在想,包装代表是最好的设计。因为我不喜欢Parent.Parent。等也不遍历控件ID以进行引用。欢迎任何评论。

答案 3 :(得分:0)

public static class Extension{
 public static Control FindControlRecursive(this Control control, string idToFind)
 {
     Control result;
     if(control != null){
        result = control.FindControl(idToFind);
     }
     if(result != null){ return result; }
     if(result == null && control.Parent != null){
         return control.Parent.FindRecursive(idToFind);
     }
     return null;
  }
}

答案 4 :(得分:-1)

你好,你可以使用WebControl选择器,它实际上是一个独立项目(license == LGPL),但仍然是主要Ra-Ajax下载的一部分......

检查代码和样本使用here ...

然后你可以从Page对象中搜索它,它会递归地寻找一个与你委托中的(无论)标准匹配的控件......