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 を実行したくありません。これを共有のマストインヘレット (抽象) クラスに配置しようとしているためです<%@ 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

ここにすべての良い情報がありますが、元の質問の実際の解決策に飛躍するために誰もそれを使用していないことに驚いています:

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

私はこのソリューションをテストしました、そしてそれはうまくいきました。

呼び出し元がLoadControlの詳細について心配する必要がないため、Rippoのソリューションよりも気に入っています。そして、これは、単にそれを返す以外に、結果のコントロールに対して行われるべき作業がもっとある場合、間違いなくより良い解決策です。

ただし、LoadControlがTemplateControlのメソッドであることに(愚かにも)気づかなかったため、CSharpAtlの回答がなければこのソリューションに到達することはできませんでした。元のポスターのように、なぜ同じエラーが発生するのかについて非常に混乱していました。共有メソッドでコントロールをロードできない理由がわかりませんでした。実際、このコンテキストでLoadControlを呼び出す方法を知っていれば問題ありません。

ブライアン

于 2010-11-09T15:02:55.960 に答える
1

LoadControlはクラスが継承するTemplateControlクラスのインスタンスメソッドであり、メソッド内にクラスのインスタンスはありません(静的メソッドであるためオブジェクトはありません)。PagePagestaticthis

于 2009-12-30T17:32:39.853 に答える
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 に答える