none
On...-Methode selbst erstellen RRS feed

  • Frage

  • Hallo,

    ich habe gerade gelesen, dass es die Form.OnFormClosing-Methode gibt, die es ermöglicht, dass auch abgeleitete Klassen das Ereignis ohne Anfügen eines Delegaten zu behandeln.

    Wie kann man dies selbst nachbilden, d.h. für eigene Ereignisse ohne Anfügen eines Delegaten?

     

    Alexander

    Samstag, 15. Oktober 2011 17:16

Antworten

  • Hallo Alexander,

    in dem Falle mache die Methode public (anstatt protected) in Form2 (im Deinem anderen Beispiel Tasks) .

    Gruß Elmar

    • Als Antwort markiert AlexanderRi Montag, 17. Oktober 2011 07:06
    Sonntag, 16. Oktober 2011 16:44
    Beantworter

Alle Antworten

  • Hallo Alexander,

    das einfachste Muster für solche Fälle wäre:

            public event EventHandler EinEreignis;
    
            protected virtual void OnEinEreignis(EventArgs e)
            {
                // In Variable zwischenspeichern falls konkurrierene Zugriffe möglich sind
                var handler = EinEreignis;
                if (handler != null)
                    handler(this, e);
            }
    
    

    Und soll das Ereignis ausgelöst werden, so wird dann die Methode aufgerufen.
    Da die Methode virtuell gekennzeichnet ist, kann sie von ableitenden Klassen direkt aufgerufen werden.
    Und eigene Behandlungen vor oder nach dem Aufruf der Basismethode vornehmen
    oder auch - in seltenen Fällen - diesen unterdrücken, und so das Ereignis unterbinden.

    Window Forms praktiziert das für alle Ereignisse nach dem Schema.
    Und verwendet intern einen EventHandlerList, um die Ereignisse zu verwalten.

    Gruß Elmar

    • Als Antwort markiert AlexanderRi Sonntag, 16. Oktober 2011 09:27
    • Tag als Antwort aufgehoben AlexanderRi Sonntag, 16. Oktober 2011 11:55
    Samstag, 15. Oktober 2011 18:25
    Beantworter
  • Hallo Elmar,
    vielen Dank für Deine Hilfe. Der Aufruf von OnEinEreignis funktioniert bei mir nicht. Was mache ich falsch?

    Alexander


     namespace WindowsFormsApplication5
    {
       public partial class Form1 : Form
       {
          public Form1()
          {
             InitializeComponent();
          }

          private void Form1_Load(object sender, EventArgs e)
          {
             //
          }

          private void buttonApply_Click(object sender, EventArgs e)
          {
             Tasks tasks = new Tasks();

             // nicht gefunden!
             // tasks.OnEinEreignis      
          }
       }

       public class Tasks
       {
          public event EventHandler EinEreignis;

          protected virtual void OnEinEreignis(EventArgs e)
          {
             var handler = EinEreignis;
             if (handler != null)
                handler(this, e);

             MessageBox.Show("Event ausgelöst");
          }
       }
    }

    Sonntag, 16. Oktober 2011 12:02
  • Hallo Alexander,

    das klappt nur, wenn man es innerhalb der Klasse bzw. in einer abgeleiteten Klasse verwendet.
    Denn auf eine protected Methode ist nur von der Klasse aus zugegriffen werden.
    Und könnte durch die Markierung als virtual mittels override durch eine abgeleitete Klasse überschrieben werden.

    Wenn Du EinEreignis und OnEinEreignis in Form1 übernimmst, so ginge das wiederum.

    Wenn Du Dir das anhand des erwähnten OnFormClosing vs. FormClosing Ereignis verdeutlichen willst:
    Innerhalb von Form1 kannst Du auf OnFormClosing zugreifen. Von ausserhalb, also z. B. aus Tasks,
    aber auch einem anderen Formular (Form2) musst Du das FormClosing Ereignis verwenden,
    da Du keinen Zugriff auf die Methode erhältst.

    Nun könntest Du zwar bei eigenen Klassen, die Methode auf public einstellen, das würde aber der Kapselung widersprechen,
    da damit die Kontrolle, wann das Ereignis ausgelöst wird, nicht mehr in der Kontrolle der Klasse liegt.

    Evtl. beabsichtigst Du aber was ganz anderes - denn das Fremdauslösen von Ereignissen wäre eher selten.
    Erläutere mal in eigenen Worten, wozu Du das Ganze in der Praxis einsetzen möchtest.

    Gruß Elmar

    Sonntag, 16. Oktober 2011 13:51
    Beantworter
  • Hallo Elmar,
    ich habe eine Form1, welche nur den Rahmen und den Button OK besitzt.
    In dieser Form1 wird eine zweite Form (Form2 randlos und kein OK-Button) angezeigt.
    Diese Vorgensweise ist so vorgegeben.
    Nun will ich mit Click-Ereignis vom OK-Button in Form1 ein Ereignis in Form2 auslösen.

    Alexander

    Sonntag, 16. Oktober 2011 14:23
  • Hallo Alexander,

    in dem Falle mache die Methode public (anstatt protected) in Form2 (im Deinem anderen Beispiel Tasks) .

    Gruß Elmar

    • Als Antwort markiert AlexanderRi Montag, 17. Oktober 2011 07:06
    Sonntag, 16. Oktober 2011 16:44
    Beantworter