LoadControl在静态/共享功能中

时间:2009-12-30 17:17:22

标签: .net asp.net vb.net dynamic-controls

任何人都知道如何动态加载共享/静态函数内的控件?函数本身位于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,因为我试图把它放在一个共享的,必须(抽象)的类中,因此没有.aspx文件写在<%@ Reference Control="~/SomeControlPath.ascx" %>中,所以班级名称不可用。

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

是的,我知道那里的静态字符串有代码味道,它实际上看起来并不像那样;为了提出这个问题,这是一个简化。

C#,VB或简单的英文解释都欢迎。

4 个答案:

答案 0 :(得分:10)

实际上,你可以这样做(它有效):

UserControl tmp0 = new UserControl();
Control ctl = tmp0.LoadControl("MyControl.ascx");

答案 1 :(得分:1)

LoadControlTemplateControl类的一个实例方法,Page类继承自该类,并且您的Page类中没有static类的实例1}}方法(没有this对象,因为它是一个静态方法)。

答案 2 :(得分:1)

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

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

我测试了这个解决方案并且它已经开始了。

我比Rippo的解决方案更喜欢它,因为它可以防止调用者担心LoadControl的细节。如果除了简单地返回它之外还有更多的工作要做,那么这绝对是一个更好的解决方案。

但是,如果没有CSharpAtl的答案,我就不会达到这个解决方案,因为我(愚蠢地)没有意识到LoadControl是TemplateControl上的一个方法。就像原版海报一样,我对于为什么会出现同样的错误感到非常困惑。我无法理解为什么在共享方法中加载控件是不行的,事实上,如果您知道如何在此上下文中调用LoadControl,那就没关系了!

布赖恩

答案 3 :(得分:0)

是不是因为你的班级无法返回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;

但是调用代码仍然需要将其强制转换为其类型...