代码之家  ›  专栏  ›  技术社区  ›  jorelli

静态/共享函数中的负载控制

  •  5
  • jorelli  · 技术社区  · 15 年前

    有人知道我如何在共享/静态函数内部动态加载控件吗?函数本身位于MustInherit/Abstract类内。(这是一个VB中的ASP.NET项目)我想这样做:
    VB:

        Public Shared Function GetWidget(ByVal name As WidgetName) As Control
            Select Case name
                Case WidgetName.Name1
                    Return LoadControl("~/Control1.ascx")
                Case WidgetName.Name2
                    Return LoadControl("~/Control2.ascx")
                Case WidgetName.Name3
                    Return LoadControl("~/Control3.ascx")
            End Select
        End Function
    

    我的C有点生锈,因此这可能有一些语法错误:

    Public Static Control GetWidget(WidgetName name)  
    {  
        switch (name)  
        {  
            Case WidgetName.Name1:  
                return LoadControl("~/Control1.ascx");  
                break;  
            Case WidgetName.Name2:  
                return LoadControl("~/Control2.ascx");  
                break;  
            Case WidgetName.Name3:  
                return LoadControl("~/Control3.ascx");  
                break;  
        }  
    }  
    

    (其中widgetname是枚举器。)

    我正在获取“如果没有类的显式实例,则无法从共享方法或共享成员初始值设定项中引用类的实例成员。”,但我不理解此错误。我理解它的含义,我只是不理解为什么编译器不将调用loadcontrol视为类的显式实例。使用loadcontrol从文件创建新控件有什么不明确的地方?我尝试创建一个新的用户控件并初始化它,然后将其设置为另一个控件,但LoadControl无效。我也不想做DirectCast,因为我正试图将它放在一个共享的mustinheret(抽象)类中,因此该类没有.aspx文件可在 <%@ Reference Control="~/SomeControlPath.ascx" %> ,因此类名不可用。

    我要做的是编写一个静态函数,它获取一些值并返回一个仅基于该控件的源文件位置的控件。最终结果是用户可修改的控件列表。它们得到一列控件,这些控件可以根据我指定的可用子控件的静态列表自由地添加、删除或重新排序。我并没有嫁给这种方法;这在很多方面都可能是错误的。

    是的,我知道静态字符串有代码味道,实际上它不像那样;它是为了问问题而简化的。

    欢迎使用C、VB或简单的英语解释。

    4 回复  |  直到 13 年前
        1
  •  0
  •   Rippo    15 年前

    是因为LoadControl无法从类中返回吗?你能试试这个吗…

        Protected Static string GetWidget(WidgetName name)  
        {  
            switch (name)  
            {  
                Case WidgetName.Name1:  
                    return "~/Control1.ascx";  
                    break;  
                Case WidgetName.Name2:  
                    return "~/Control2.ascx";  
                    break;  
                Case WidgetName.Name3:  
                    return"~/Control3.ascx";  
                    break;  
          }  
     } 
    

    然后像这样调用方法

    ... = LoadControl(GetWidget(name));
    

    我怀疑另一种选择是控制局面

    Control c;
    ...
    Case ...
       c = (ControlName)LoadControl("~/Control1/.ascx");
       break;
    ...
    return c;
    

    但是,调用代码仍然需要将其转换回其类型…

        2
  •  10
  •   Gallegher    13 年前

    实际上,你可以这样做(它工作):

    UserControl tmp0 = new UserControl();
    Control ctl = tmp0.LoadControl("MyControl.ascx");
    
        3
  •  1
  •   CSharpAtl    15 年前

    LoadControl 是上的实例方法 TemplateControl 班级哪个 Page 类继承自,并且您没有 在您的 static 方法(没有 this 对象,因为它是静态方法)。

        4
  •  1
  •   BrianFinkel    14 年前

    这里的所有信息都很好,但我很惊讶没有人使用它来实现对原始问题的实际解决:

    Public Shared Function GetWidget(ByVal name As WidgetName,
                                     ByVal onTemplate As TemplateControl) As Control
        Select Case name
            Case WidgetName.Name1
                Return onTemplate.LoadControl("~/Control1.ascx")
            Case WidgetName.Name2
                Return onTemplate.LoadControl("~/Control2.ascx")
            Case WidgetName.Name3
                Return onTemplate.LoadControl("~/Control3.ascx")
        End Select
    End Function
    

    我测试了这个溶液,结果很好。

    我比Ripo的解决方案更喜欢它,因为它可以防止调用者担心LoadControl的细节。如果要对结果控件做更多的工作,而不是简单地返回它,那么这绝对是一个更好的解决方案。

    如果没有CSharpatl的回答,我就不会得到这个解决方案,因为我(愚蠢地)没有意识到LoadControl是TemplateControl上的一个方法。和原来的海报一样,我对为什么会出现同样的错误感到非常困惑。我不明白为什么在共享方法中加载控件是不正常的,事实上,如果您知道如何在此上下文中调用LoadControl,这是正常的!

    布瑞恩