2009-12-30 38 views
5

任何人都知道如何动态地加载共享/静态函数内的控件?函数本身是mustinherit/abstract类的内部。 (这是在VB ASP.NET项目)我想要做这样的事情:
VB:LoadControl在静态/共享函数

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或纯英文解释都欢迎。

回答

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; 

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

+0

它是不是被退回是什么......这是你无法从内部调用LoadControl方法静态方法...因为没有实例。 – CSharpAtl 2009-12-30 17:35:31

+0

不用担心,去过那里!拿起一杯咖啡,然后离开啤酒:) :) – Rippo 2009-12-30 17:35:46

+0

@CSharpAtl - 你是正确的,这就是为什么我建议替代品。 – Rippo 2009-12-30 17:36:32

1

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

+0

啊,谢谢你的技术人员,这有助于了解。我现在明白错误。到目前为止,我还没有真正考虑LoadControl定义的上下文,我只是认为它是理所当然的并使用它。 – jorelli 2009-12-30 17:36:46

+0

在你的智能感应菜单中...'LoadControl'不应该出现在你的静态方法中。 – CSharpAtl 2009-12-30 17:40:14

+0

是的,它没有。我用签名指定方法的主体作为实例方法编写了方法的主体,然后决定如果它被共享,它会更容易读取,所以我更改了签名,这是我开始看到错误并且不太明白的时候它。 – jorelli 2009-12-30 17:43:25

0

所有良好的信息在这里,但我很惊讶,没有人用它来跃升到一个实际的解决方案,原题:

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细节。如果除了简单地返回结果之外还有更多的工作要做,那么这绝对是一个更好的解决方案。

虽然我没有意识到LoadControl是TemplateControl上的一个方法,但我不会在没有CSharpAtl的答案的情况下达成此解决方案。就像原来的海报一样,我对我为什么会遇到同样的错误感到非常困惑。我无法理解,为什么在共享方法中加载控件是不行的,事实上,如果您知道如何在此上下文中调用LoadControl,那么也可以!

布赖恩

10

其实,你可以做这样的(它的工作原理):

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