none
Das erneute öffnen einer windows.form verhindern RRS feed

  • Frage

  • Hallo,

    folgendes Script habe ich:

     

     

    private void buttonlektion1_Click(object sender, EventArgs e)

    {

     

     

    Lektion1 l1 = new Lektion1();

    l1.TopLevel =

     

    false;

     

     

    this.Controls.Add(l1);

    l1.Show();

     

     

    }

    Wenn ich allerdings mehrmals auf das Button klicke, wird auch das Formular mehrmals geöffnet. wie kann ich das verhindern?

     

    danke

    Thomas

    Dienstag, 23. November 2010 18:10

Alle Antworten

  • Hallo Thomas,

     

    am einfachsten wäre es, wenn du den Button nach dem ersten klick deaktivierst. Dann kann er kein zweites mal betätigt werden:

    (sender as Button).Enabled = false;
    

     

     

    Ich hoffe das hilft dir weiter. Ansonsten frage bitte gezielt nach!

     

    Viele Grüße

    Holger M. Rößler

    Dienstag, 23. November 2010 18:44
  • Hallo,

    eine Weitere (einfache) Möglichkeit wäre es eine Boolische Variable zu setzen (wie zB. FormIsOpen) und diese dann
    auf True zu setzen nachdem das Fenster zum ersten Mal angezeigt wurde.

    Beim nächsten Start ist diese Variable dann True und du weißt, dass bereits ein Fenster offen ist.


    MfG, Sebastian Gross
    Dienstag, 23. November 2010 22:45
  • Hi Sebastian,

    meiner Ansicht nach keine gute Idee! Warum sollte der Button noch enabled sein, wenn ein Klick auf diesen eh nichts mehr bewirkt? Das verwirrt den Benutzer nur...

    Viele Grüße

    Holger M. Rößler

    Dienstag, 23. November 2010 23:00
  • Hallo,

    mein Problem ist konkret folgendes:

    ich möchte, dass sich die Form nur einmal öffnen lässt. Ein zweiter Versuch sollte ignoriert werden. Bas Button, welches dieses Ereignis auslöst, sollte jedoch nicht "grau" danach sein, denn wenn die besagte Form wieder regulär geöffnet werden soll, soll das Button ja weiterhin funktionieren.

    ich bin absoluter neuling, muss mich aber damit leider auseinandersetzen...

    Mfg Thomas

    Dienstag, 23. November 2010 23:31
  • Hallo Thomas,

    auch dir möchte ich die Frage stellen, welchen Sinn ein benutzbarer Button macht, hinter dem keine Funktionalität steckt? Erkläre mal einem Benutzer, dass er den Button zwar anklicken kann, aber dann nichts passiert!

    Du kannst den Button ja wieder aktivieren, wenn der Benutzer das Fenster schliesst. Dazu hängst du dich an das Closed Event und kannst darin den Button wieder aktivieren. Somit kann der Benutzer den Button wieder verwenden. Aber nur dann, wenn er das Fenster geschlossen hat.

     

    private void buttonlektion1_Click(object sender, EventArgs e) 
    {
     Lektion1 l1 = new Lektion1(); 
     l1.TopLevel = false; 
     l1.Closed += (sender, e) => this.buttonlektion1.Enabled = true;
    
     this.Controls.Add(l1); 
     l1.Show(); 
    
     (sender as Button).Enabled = false;
    }
    
    
    

    So müsste es eigentlich funktionieren. Kann es leider gerade nicht testen. Übrigens setzt dieses Beispiel  mindestens .net 3.5 vorraus. Solltest du eine frühere .net Version einsetzen so musst du den Lambdaausdruck durch einen "normalen" Delegate ersetzen.

    Achja, warum addest du das "Lektion1" Fenster zur aufrufenden Form hinzu? Das macht ja eigentlich in deinem Beispiel ja nur Sinn, damit der Garbage Collector dir das Fenster nicht gleich vor der Nase wegfrisst. Wenn dass dein Gedanke war, so solltest du lieber eine Klassenglobale Referenz in der aufrufenden Form einbetten, anstatt jedes neue Fenster zu seinen Childs "hinzuzuadden" (was in meinen Augen eh Käse ist). Denn sonst musst die gepufferten Fenster natürlich auch wieder aus der Liste entfernen, da diese sonst im Laufe der Zeit volläuft.

    Viele Grüße

    Holger M. Rößler

    Mittwoch, 24. November 2010 07:55
  • Hallo Thomas,

    wie Holger bin ich der Meinung, Du solltest das zu Ende denken.

    Das "grau", sprich das Deaktivieren einer Schaltfläche, ist eine gängige Praxis unter Windows.
    Schaltflächen, die keine Funktion ausführen können, sollten nicht zugänglich sein
    und dies dem Benutzer optisch signalisieren.

    Da es sich hier mit der Schaltfläche ein Formular geöffnet wird, hättest Du als weitere Alternativen:

    Wenn das Formular bereits geöffnet ist, hole es wieder in den Vordergrund, in dem Du die Form.Activate Methode aufrufst.
    Dazu kannst Du die Formularinstanz im aufrufenden Formular als Instanzvariable zwischenspeichern
    oder aber über Application.OpenForms prüfen, ob das Formular bereits offen ist.

    Oder aber Du verwendest die ShowDialog Methode .
    Dabei ist allerdings das aufrufende Formular nicht zugänglich, bis das Formular geschlossen wird.

    Irritieren tut mich allerdings die Zeile:

    this .Controls.Add(l1);

    denn ein Formular sollte nicht in die Steuerelement-Auflistung eines anderen Formulars eingefügt werden.
    Wenn Du Deine "Lektionen" in ein Formular einbetten willst, wäre dafür ein Benutzersteuerelemnent (UserControl )
    besser geeignet.

    Gruß Elmar

    Mittwoch, 24. November 2010 10:23
  • Hallo Elmar, hallo Thomas,

    mal wieder eine Punktlandung von Elmar.

    Das Formular modal anzuzeigen ist wesentlich eleganter und auch weit weniger aufwändig als die enablerei bzw. disablerei mit dem Button. 

    Viele Grüße

    Holger M. Rößler

    Mittwoch, 24. November 2010 12:35
  • Hallo Holger,

    ich hatte die Antwort schon fast abgeschickt, als mir das mit dem Controls.Add auffiel...

    Und so gilt: Ob die "Landung" am richtigen Ort stattfindet hängt davon ab,
    was das mit dem Einfügen in der Steuerelement-Auflistung auf sich hat
    (dann wäre das Form nämlich nichts weiter als ein verbogenes UserControl...)

    Gruß Elmar
    Mittwoch, 24. November 2010 13:47
  • Hallo Elmar,

    wie ich oben bereits geschrieben habe, ist es wohl besser eine Referenz in der Parentform Klassenglobal zu halten, anstelle diese in der Methode jedes mal eine neue zu erstellen. Würde Thomas die Referenz momentan nicht als UserControl hinzuadden, würde ihm mit ein bisschen Pech der Garbage Collector die Form vor der Nase wegentsorgen...

    Daher mein Vorschlag:

    public class Hauptform : Form {
     private Lektion1 l1;
    
     public Hauptform() {
      this.l1 = null; //Der sauberkeit halber ;)
     }
    
     private void buttonlektion1_Click(object sender, EventArgs e) 
     {
      this.l1 = new Lektion1(); 
      this.l1.TopLevel = false; 
      //this.Controls.Add(l1); <-- Auskommentiert, nicht notwendig
      this.l1.ShowDialog(this); 
     }
    }
    
    

    Ich denke mal, so sollte es passen!

    Viele Grüße

    Holger M. Rößler

    • Bearbeitet Holger M. Rößler Donnerstag, 25. November 2010 21:00 Konstruktor heisst wie Klasse!
    Mittwoch, 24. November 2010 14:30