2009-07-18 13 views
1

Im Wesentlichen habe ich einen Platzhalter auf der Seite dynamisch beim Laden der Seite hinzugefügt.ASP.net dynamisch Steuerelement Ereignisbehandlung erstellt

Dann habe ich ein zusammengesetztes Steuerelement, das zum Platzhalter hinzugefügt und während der Laufzeit für bestimmte Seitenereignisse angezeigt wird. Das zusammengesetzte Steuerelement verfügt über eine Schaltfläche. Ich habe einen öffentlichen Eventhandler für die Schaltfläche, die im Composite-Steuerelement verfügbar ist, aber keinen direkten Zugriff auf diesen Eventhandler im Seitencode.

die Steuerung anzuzeigen, würde ich den folgenden Aufruf zum Beispiel machen:

MyControl.Create(args, new EventHandler(OnClick)); 

dann auf der Seite I protected void OnClick(object o, EventArgs args) {}

Natürlich haben würde, wenn ich create() ich das meine Eventhandler verdrahten nennen Klick-Ereignis des Composite-Steuerelements. So weit, ist es gut. Wenn der Button geklickt ist, wird der Klick auf die Schaltfläche wie erwartet zum Steuerelement zurückgesendet. Das Ereignis kehrt jedoch nie zum Ereignishandler der Seite zurück.

Ich weiß, dass das Problem auf Postback auftritt. Der Versuch, die Schaltfläche bei Init zu verkabeln, zu laden oder zu erstellen, scheitert jedoch daran, die Verdrahtung beizubehalten, damit das Ereignis auf der Seite gehandhabt werden kann. Was ich möchte, ist die Fähigkeit, den Eventhandler während der Laufzeit an das Composite-Steuerelement zu übergeben, und damit das Composite-Steuerelement das Ereignis korrekt an die Seite beim Postback zurücksendet.

Interessanterweise, wenn ich OnBubble mit benutzerdefinierten Eventargs aufrufen kann ich das sprudelnde Ereignis auf der Seite abfangen. Das Problem ist jedoch, dass sich mein Platzhalter auf der Seite befindet. Wenn ich z. B. versuche, in einem UserControl MyControl.Create() aufzurufen, geht die Blase (wie erwartet) zur Seite und nicht zum UserControl. Daher würde ich den Eventhandler lieber deklarieren, anstatt OnBubble zu überschreiben (UserControls und andere Steuerelemente, die MyControl deklarieren, würde es für Button-Click-Ereignisse praktisch nutzlos machen).

Ich hoffe, jemand hat ein wenig Einblick in das Problem. Es scheint ein interessantes Problem zu sein, aber vielleicht gibt es keine Lösung, das Steuerelement explizit auf der Seite zu deklarieren und das Ereignis entweder direkt im Markup oder beim Seitenladen zu verkabeln. Ich würde erwägen, die Schaltfläche einen asynchronen Rückruf durchführen zu lassen, würde jedoch lieber die standardmäßige ASP.NET-Ereignisbehandlung verwenden, wenn dies möglich ist.

Danke!

Um eine Klarstellung hinzuzufügen: der Aufruf MyControl.Create() generiert tatsächlich ein Ereignis, das die Create() Methode der Composite Control aufruft. Das ist alles gut und gut, aber es ist erwähnenswert, dass die MyControl.Create() Methode keinen direkten Zugriff auf das Steuerelement hat. Dies sollte sinnvoll sein, da das Steuerelement auf der Seite onload auf nicht in Markup hinzugefügt wird.

Weiterer Code:

MyControl : CompositeControl 
{ 
    public event EventHandler Click; 

    //I have a create method 
    void Create(args, EventHandler click) 
    { 
      this.Click = click; 
      //other processing 
    } 

    //then the button is wired up. I've tried in OnInit(), OnLoad() 
    void CreateChildControls() 
    { 
      MyButton.OnClick += Click; 
    } 

    //if I wire up the button to a default handler I can check if 
     Click is not null and send the click event onto the next handler 
    //this is where the bubble event works, but the wiring fails 
} 

Edit: Mein Versuch, die Eventhandler in der Session zu speichern und Draht auf die Schaltfläche auf Postbacks up erfolgreich war. Ich betrachte diese gute Praxis nicht, und ich glaube nicht, dass sie tatsächlich meinem Zweck dient. In diesem Fall wird das Ereignis auf der Seite beispielsweise wie erwartet ausgeführt, jedoch mit nicht standardmäßigen Seitenverhalten. Zum Beispiel gibt Response.Redirect() eine Ausnahme aus. Dies sollte sinnvoll sein, da der Eventhandler während des Postbacks wahrscheinlich Statusinformationen verloren hat. Ein paar Gedanken: 1. Ist es möglich, dass ich ein benutzerdefiniertes Bubble-Ereignis erstellen könnte, das irgendwie mit diesem Steuerelement verbunden ist? Dies erscheint plausibel, aber das Problem des Seitenpostbacks lässt mich wieder mit dem gleichen Problem, wo die Blase gehen sollte.Also, wenn ich create() aufrufen, ist es möglich, dass ich das UserControl automatisch als Ziel für die Blase registrieren kann? Es scheint schwierig. 2. Gibt es einen Punkt im Seitenlebenszyklus, in dem ich das Ereignis für den deklarierten EventController von UserControl neu verbinden kann, damit der Delegat beim Postback korrekt aufgerufen wird? Dies scheint mir zu fehlen. Der Eventhandler wird auf einem Postback erstellt, ist aber verloren, da es nicht in UserControl während OnClick neu erstellt wird. Ich möchte nicht, dass das UserControl das Ding explizit neu erstellen muss, sondern dass das untergeordnete Steuerelement es für das UserControl neu erstellen soll. Es klingt wie eine einfache Anfrage, aber mit der UserControl aus der Schleife, kann ich nach dem Unmöglichen fragen.

+0

Können Sie mehr Code dort posten, wo Sie den Handler tatsächlich verkabeln? – user134706

+0

Ich bin ziemlich sicher, dass Sie Speicher verlieren, indem Sie den Event-Handler dort speichern;) – user134706

Antwort

0

Was motiviert Sie, das Steuerelement dynamisch in einen Platzhalter einzufügen? Eine Seite existiert nicht wirklich zwischen Anforderungen, so dass alle Steuerelemente, die dynamisch eingefügt werden, nicht überleben. Du müsstest es im Grunde fälschen.

Eine Option, die Sie in Betracht ziehen sollten, ist das Schreiben eines benutzerdefinierten Steuerelements mit unterschiedlichen Rendermodi, das über eine konsistente Ereignisschnittstelle verfügt. Eine andere Möglichkeit besteht darin, ein ASP.NET-MultiView-Steuerelement zu verwenden, das nur die sichtbare Ansicht im HTML-Code rendert, die Ereignishandler jedoch weiterhin in den unsichtbaren Ansichten verwaltet.

+0

Danke für die Antwort. Das Steuerelement wird häufig in einer Reihe von Anwendungen und auf fast allen Seiten verwendet. Die Hauptmotivation für den Versuch, das Steuerelement dynamisch in die Seite einzufügen, besteht darin, ein httpmodul zum Einfügen des Steuerelements mithilfe einer einzigen Zeile in einer CONFIG-Datei zu verwenden ... für einfache Entwicklung, einfache Wiederverwendung von Code und bessere Seitenpflege. Ich schätze die Vorschläge und werde mehr in sie schauen. Ich poste zurück, wenn ich eine Lösung finde, die ich dort verwenden kann. –

0

Okay, korrigiere mich, wenn ich falsch liege, instantiiert deine Create() -Methode und setzt deine innere Kontrolle in einen bekannten Zustand; Ich sehe, Sie haben bereits einen Verweis auf den Button, warum brauchen Sie an diesem Punkt ein zusätzliches Click-Ereignis?

Wenn Sie Create() aufrufen, initialisieren Sie das Steuerelement und seine Schaltfläche. Wenn Sie dann wissen, dass die Schaltfläche vorhanden ist, verknüpfen Sie den Ereignishandler mit dem übergebenen Parameter.

MyControl : CompositeControl 
{ 
    void Create(args, EventHandler click) 
    { 
     // init & set up your control 

     // other processing 

     MyButton.OnClick += click; 
    } 
} 
+0

Der Eventhandler selbst wird auf der übergeordneten Seite oder UserControl deklariert. Es gibt eigentlich keinen Bedarf für einen zusätzlichen Event-Handler, aber da dieser bei Postbacks verloren geht, habe ich einen in das Control geschrieben, damit ich das Event abfangen und OnBubble aufrufen kann. Ich habe bemerkt, dass, wenn ich den Eventhandler in der Sitzung speichern und neu verbinden oninit oder onload die Seite oder UserControl wird das Ereignis erfassen, aber nicht in einem stabilen Zustand. –

1

Sie haben nicht speziell erwähnt, an welchem ​​Punkt des Seitenlebenszyklus Sie diese Steuerelemente erstellen und hinzufügen. Damit das Postback funktioniert, muss die gesamte Erstellung (und Verdrahtung) und "Neuerstellung" vor dem Ereignis page_load erfolgen.

Tun Sie es bei page_init und der Viewstate-Mechanismus sollte die Postback-Werte übernehmen, wenn die IDs identisch sind.

Ich habe über eine andere Methode, die hier kommen aber: http://www.codeproject.com/KB/viewstate/retainingstate.aspx

0

Sie immer die gleiche ID setzen sollte dynamisch Kontrollen erstellt, wenn Sie es nicht manchmal,

diese

Hoffnung nicht angehoben Ereignisse steuern Hilfe.

Verwandte Themen