2009-12-30 13 views
5

Wer weiß, wie ich ein Steuerelement innerhalb einer geteilten/statischen Funktion dynamisch laden kann? Die Funktion selbst ist innerhalb einer Mustinherit/Abstract-Klasse. (Es ist ein ASP.NET-Projekt in VB) ich so etwas wie dies tun will:
VB:LoadControl in der statischen/geteilten Funktion

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 

meine C# ist ein wenig rostig, so könnte dies einige Syntaxfehler hat:

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; 
    } 
} 

(Wobei WidgetName ein Enumerator ist.)

Ich bekomme "Kann nicht auf eine Instanz Mitglied einer Klasse innerhalb einer gemeinsamen Methode oder Shared-Member-Initialisierer ohne eine explizite Instanz der Klasse verweisen.", Aber ich don ' Ich verstehe diesen Fehler. Ich verstehe, was es bedeutet, ich verstehe einfach nicht, warum der Aufruf von LoadControl vom Compiler nicht als explizite Instanz der Klasse angesehen wird. Was ist nicht explizit an der Verwendung von LoadControl zum Erstellen eines neuen Steuerelements aus einer Datei? Ich habe versucht, ein neues Benutzersteuerelement zu erstellen und es zu initialisieren, und es dann zu einem anderen Steuerelement mit LoadControl ohne Erfolg zu setzen. Ich möchte auch nicht eine DirectCast, da ich versuche, dies in eine gemeinsame, MustInheret (abstrakte) -Klasse, die daher keine .aspx-Datei in eine <%@ Reference Control="~/SomeControlPath.ascx" %> schreiben, so dass der Klassenname nicht verfügbar ist .

Ich versuche, eine statische Funktion zu schreiben, die einen Wert nimmt und ein Steuerelement zurückgibt, das nur auf dem Speicherort der Quelldatei des Steuerelements basiert. Das Endergebnis ist eine benutzerdefinierbare Liste von Steuerelementen. Sie erhalten eine Spalte mit Steuerelementen, die sie basierend auf einer statischen Liste der von mir angegebenen untergeordneten Steuerelemente hinzufügen, entfernen oder neu anordnen. Ich bin nicht mit diesem Ansatz verheiratet; es könnte in mehr als einer Hinsicht falsch liegen.

Ja, ich weiß, dass die statischen Zeichenketten, die da sind, Code riechen, sieht nicht wirklich so aus; es ist eine Vereinfachung, um die Frage zu stellen.

C#, VB oder einfache englische Erklärungen alle willkommen.

Antwort

0

Liegt das daran, dass LoadControl nicht von Ihrer Klasse zurückgegeben werden kann? Können Sie diese stattdessen versuchen ...

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; 
     } 
} 

und rufen Sie vermuten, dass die Methode, wie

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

ich, dass die andere Alternative ist die Steuerung

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

jedoch der Angerufene Code zu werfen würde es noch zu seinem Typ zurückwerfen müssen ...

+0

Es geht nicht darum, was zurückgegeben bekommen ... es ist, dass Sie nicht die Loadcontrol-Methode von innen anrufen die statische Methode ... weil es keine Instanz gibt. – CSharpAtl

+0

Keine Sorge, war da! Schnappen Sie sich einen Kaffee und bleiben Sie vom Bier :) :) – Rippo

+0

@CSharpAtl - Sie sind richtig, weshalb ich eine Alternative vorgeschlagen habe. – Rippo

1

LoadControl ist eine Instanzmethode für die TemplateControl Klasse, die die Page Klasse erbt, und Sie haben keine Instanz der Page Klasse innerhalb Ihrer static Methode (es gibt kein this Objekt, weil es eine statische Methode ist).

+0

ah, danke für die technischen Daten das ist hilfreich zu wissen. Ich verstehe den Fehler jetzt. Bis jetzt hatte ich nicht wirklich viel über den Kontext der LoadControl-Definition nachgedacht, ich nahm es einfach als selbstverständlich hin und benutzte es. – jorelli

+0

In Ihrem IntelliSense-Menü ... sollte 'LoadControl' in Ihrer statischen Methode nicht als Option erscheinen. – CSharpAtl

+0

Ja, tut es nicht. Ich schrieb den Hauptteil der Methode mit der Signatur, indem ich sie als Instanzmethode spezifizierte, dann entschied ich, dass es einfacher gelesen werden würde, wenn es geteilt würde, also änderte ich die Signatur, als ich anfing, den Fehler zu sehen und nicht ganz verstand es. – jorelli

0

Alle gute Informationen hier, aber ich bin überrascht, dass niemand sie den Sprung zu einer tatsächlichen Lösung auf die ursprüngliche Frage zu machen, verwendet hat:

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 

ich diese Lösung getestet und freigegegeben.

Ich mag es besser als Rippos Lösung, weil es verhindert, dass der Anrufer sich um die Details von LoadControl kümmern muss. Und dies ist definitiv eine bessere Lösung, wenn mehr Arbeit an der resultierenden Kontrolle zu leisten ist, als sie einfach zurückzugeben.

Ich hätte diese Lösung ohne CSharpAtls Antwort jedoch nicht erreicht, weil ich (dumm) nicht erkannt habe, dass LoadControl eine Methode auf TemplateControl ist. Wie beim ursprünglichen Poster war ich sehr verwirrt darüber, warum ich den gleichen Fehler bekam. Ich konnte nicht verstehen, warum es nicht in Ordnung wäre, ein Steuerelement in einer gemeinsamen Methode zu laden, und tatsächlich ist es in Ordnung, wenn Sie wissen, wie man LoadControl in diesem Kontext aufruft!

Brian

10

Eigentlich Sie es so machen kann (es funktioniert):

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