2010-06-21 5 views
10

In meiner C# -Anwendung habe ich einen Optionsdialog, der über einen Menübefehl geöffnet werden kann.Wie kann ich eine einzelne Instanz erstellen (keine Anwendung)?

Ich möchte sicherstellen, dass der Optionsdialog nur eine Instanz hat (Benutzer kann nicht mehr als ein Optionsfenster zu einem bestimmten Zeitpunkt öffnen), ohne es modal zu machen.

Auch wenn der Benutzer dieses Fenster bereits geöffnet hat und er in den Menüeintrag klickt, um es wieder zu öffnen, macht die App nur das bereits sichtbare Formular zum obersten Fenster.

Kann mir jemand Hinweise geben, wie diese Aufgaben ausgeführt werden?

Vielen Dank.

Antwort

6

Sie müssen diese Form als Eigenschaft

Form1 myForm = null; 
private void Form1_FormClosed(object sender, FormClosedEventArgs e) 
{ 
    myForm = null; 
} 

private void ShowForm() 
{ 
    if (myForm != null) 
    { 
     myForm.BringToFront(); 
    } 
    else 
    { 
     myForm = new Form1; 
     myForm.Show(); 
    } 
} 
+0

Erklären Sie einfach myForm als statisch, um mit dem FormClosed-Ereignis meiner Optionen erreichbar zu sein (um myForm wieder auf Null zu setzen). – RHaguiuda

17

Nun, der einfachste Weg besteht darin, ein statisches Feld zu haben, das einen Verweis auf die einzelne Instanz oder null speichert, und dann eine Methode, um es abzurufen oder ein neues zu erstellen.

Beachten Sie, dass dies ist nicht das gleiche wie machen es ein Singleton - weil ich davon ausgehen, wenn das Formular geschlossen ist, möchten Sie beim nächsten Mal eine neue Instanz erstellen. (Die Alternative - es versteckt und Wiederverwendung es - in STO Antwort angezeigt.) Sie können so etwas wie dies wollen:

public class OptionsDialog : Form 
{ 
    private static OptionsDialog openForm = null; 

    // No need for locking - you'll be doing all this on the UI thread... 
    public static OptionsDialog GetInstance() 
    { 
     if (openForm == null) 
     { 
      openForm = new OptionsDialog(); 
      openForm.FormClosed += delegate { openForm = null; }; 
     } 
     return openForm; 
    } 
} 

Sie möchten die Methode, um führen die „bringen sie an die Front“ Schritte und , Na sicher.

+0

Hallo @Jon, können Sie bitte ein Beispiel angeben? – RHaguiuda

+0

@RHaguiuda: Was willst du außer dem Code, den ich gegeben habe? –

+1

Hmm, ich kann sehen, woher diese Anfrage kam, so sah die Post ursprünglich nicht aus. Schnellste Waffe im Westtrick? –

2

können Sie folgenden Code verwenden:

private MyDialogForm _FormInstance; 

public void ShowOptions() 
{ 
    if (_FormInstance == null) 
    { 
     _FormInstance = new MyDialogForm(); 
     _FormInstance.FormClosing += (s,e) => 
     { 
      e.Cancel = true; 
      _FormInstance.Hide(); 
     } 
     } 
    _FormInstance.Show(); 
} 
0

Ich nehme an, Sie mindestens zwei Formen haben. Ein Formular, nennen Sie es frmMain, ermöglicht es Ihnen, frmOptions zu öffnen. In frmMain, eine Variable vom Typ frmOptions folgendermaßen hinzu:

public partial class frmMain : Form 
{ 
    private frmOptions optionsInstance = null; 
    ... 

In der Routine, die den Optionen-Dialog öffnet sich, fügen Sie diese:

if (optionsInstance == null || !optionsInstance.Visible) 
{ 
    optionsInstance = new frmOptions(); 
    optionsInstance.Show(); 
} 

Wenn frmOptions schließt nicht optionsInstance Null sein, so dass das, Warum prüfen Sie, ob es sichtbar ist, bevor Sie eine Instanz von frmOptions instanziieren?

Wenn dies nicht für Sie funktioniert, könnten Sie einen Mutex versuchen, aber das ist wahrscheinlich zu viel.

10

Sie müssen verhindern, dass das Formular geschlossen wird. Wenn Sie dies nicht tun, wird das Formular entsorgt und unbrauchbar. Sie können dies tun, indem Sie die Formclosing Ereignis Umsetzung:

protected override void OnFormClosing(FormClosingEventArgs e) { 
     if (e.CloseReason == CloseReason.UserClosing) { 
      this.Hide(); 
      e.Cancel = true; 
     } 
    } 

Um es ein Singleton zu machen, halten nur den Überblick über die Lebensdauer der Form in der Hauptform Klasse:

frmOptions options; 

    private void btnShowOptions_Click(object sender, EventArgs e) { 
     if (options == null) { 
      options = new frmOptions(); 
      // To make absolutely sure: 
      options.FormClosed += (o, ea) => options = null; 
     } 
     else { 
      options.WindowState = FormWindowState.Normal; 
     } 
     options.Show(); 
    } 
+0

Danke für diese Antwort, können Sie erklären '(o, ea) =>' Ich weiß, dass Sie das Formular zurück auf null setzen, aber ich verstehe diese Syntax nicht – meda

+2

Es ist ein Lambda-Ausdruck. Ich würde normalerweise schreiben (Absender, e) => aber diese Namen sind bereits in Gebrauch. –

+0

Vielen Dank für die Klärung – meda

0

Basierend auf Jon Skeet's answer, Ich verwende den folgenden Code zum Anzeigen eines Formulars als modales Dialogfeld.

 if (this.aboutForm == null) 
     { 
      this.aboutForm = new AboutForm(); 
      this.aboutForm.FormClosed += (sender2, e2) => { this.aboutForm = null; }; 
      this.aboutForm.ShowDialog(this); 
     } 
     else 
     { 
      this.aboutForm.Focus(); 
     } 

Ich habe, dies zu tun, weil ich einen Menüpunkt habe die über Formular im Menü des Hauptformulars anzuzeigen, und im Kontextmenü des Symbols informieren.Wenn ich das About-Formular über das Menü des Hauptformulars öffne, kann ich immer noch eine andere Instanz öffnen, indem ich den Kontextmenüpunkt des Benachrichtigungssymbols benutze.

Verwandte Themen