5

有人知道我如何在共享/静态函数中动态加载控件吗?函数本身位于 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

4 回答 4

11

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

UserControl tmp0 = new UserControl();
Control ctl = tmp0.LoadControl("MyControl.ascx");
于 2011-07-24T21:45:07.377 回答
1

LoadControl是类继承的TemplateControl类的实例方法,并且您的方法中没有该类的实例(没有对象,因为它是静态方法)。PagePagestaticthis

于 2009-12-30T17:32:39.853 回答
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 就可以了!

布赖恩

于 2010-11-09T15:02:55.960 回答
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;

但是调用代码仍然需要将其转换回它的类型......

于 2009-12-30T17:26:24.640 回答