【问题标题】:Nested User Controls - how to best get a reference to an ancestor control嵌套用户控件 - 如何最好地获取对祖先控件的引用
【发布时间】:2009-01-15 01:01:48
【问题描述】:

我意识到这里放不下很多代码,但我要求提供大致的方向或指针。

我有嵌套六层的 .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 可能会改变......

有没有不错的选择?

【问题讨论】:

    标签: .net user-controls nested


    【解决方案1】:

    请记住,组件最好是无知的。您永远不希望任何控件了解层次结构中自身之上的任何内容,并且只了解层次结构中自身之下的控件的界面知识。从长远来看,这种架构方法将为您节省很多痛苦和痛苦,并将避免像您现在这样的情况。

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

    因此,我将创建一个名为 ParentTab 之类的属性,并将此属性设置为页面中某处或某个控件内的 MyTab 引用,该引用确实并且应该对 MyTab 和您的控件都具有可见性。

    【讨论】:

      【解决方案2】:

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

      现在,如果它是一个您无法控制使用的通用组件,或者在许多用例中都需要它,那么您需要为父组件添加属性以告诉您它们要保持解耦。

      【讨论】:

        【解决方案3】:

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

        我的设计类似——最外层的包装容器管理对象持久性,每个控件都可以将其状态保存到该管理器。我现在认为包装代表是最好的设计。因为我不喜欢 Parent.Parent。等等,也不是为了参考而遍历控件 ID。欢迎任何cmets。

        【讨论】:

          【解决方案4】:
          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;
            }
          }
          

          【讨论】:

            【解决方案5】:

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

            查看代码和示例使用here...

            然后您可以从 Page 对象中进行搜索,它会递归地在委托中查找与您的(任何)条件匹配的控件...

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-10-03
              • 2014-02-18
              • 2020-06-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多