2010-06-21 24 views
10

Nella mia applicazione C# ho una finestra di dialogo delle opzioni che può essere aperta da un comando di menu.Come posso creare un singolo modulo di istanza (non un'applicazione)?

Voglio garantire che la finestra di dialogo delle opzioni abbia una sola istanza (l'utente non può aprire più di una finestra di opzioni in un dato momento) senza renderla modale.

Anche se l'utente ha già questa finestra aperta, e fa clic sulla voce di menu per aprirla di nuovo, l'app fa semplicemente diventare il modulo già visibile la finestra più in alto.

Qualcuno può indicarmi le indicazioni su come eseguire questi compiti?

Grazie mille.

risposta

6

Avrete bisogno di questa forma come proprietà

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

Dichiara semplicemente myForm come statico per essere accessibile dalle mie opzioni form Evento FormClosed (per rendere myForm = null di nuovo). – RHaguiuda

17

Bene, il modo più semplice è disporre di un campo statico che memorizza un riferimento alla singola istanza o null e quindi un metodo per recuperarlo o crearne uno nuovo.

Si noti che questo non è come se fosse un singleton, perché presumo che se il modulo è chiuso, si vorrebbe creare una nuova istanza la volta successiva. (L'alternativa - nasconderlo e il riutilizzo di esso - è mostrato nella risposta di STO.) Si consiglia qualcosa di simile:

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

Si consiglia di rendere il metodo eseguire il "bring in primo piano" passi pure , ovviamente.

+0

Ciao @Jon, puoi fornire un esempio, per favore? – RHaguiuda

+0

@RHaguiuda: cosa vuoi oltre al codice che ho dato? –

+1

Hmm, posso vedere da dove proveniva quella richiesta, non è come appariva il post in origine. La pistola più veloce nel trucco West? –

2

è possibile utilizzare il codice come questo:

private MyDialogForm _FormInstance; 

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

presumo di avere almeno due forme. Un modulo, chiamalo frmMain, ti consente di aprire frmOptions. In frmMain, aggiungere una variabile di tipo frmOptions come questo:

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

Nella routine che si apre la finestra di dialogo Opzioni, aggiungere questo:

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

Quando frmOptions chiude, optionsInstance non ci sarà nulla, in modo che perché verifichi se è visibile prima di istanziare un'istanza di frmOptions.

Se questo non funziona, puoi provare un mutex, ma probabilmente è eccessivo.

10

È necessario impedire la chiusura del modulo. In caso contrario, il modulo verrà eliminato e diventa inutilizzabile. È possibile farlo implementando l'evento FormClosing:

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

per renderlo un Singleton, basta tenere traccia del tempo di vita della forma nella classe principale forma:

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

grazie per questa risposta, puoi spiegare '(o, ea) =>' So che hai impostato il modulo su null ma non capisco questa sintassi – meda

+2

È un'espressione lambda. Scrivo normalmente (mittente, e) => ma quei nomi sono già in uso. –

+0

Grazie per il chiarimento – meda

0

Sulla base di Jon Skeet's answer, Sto usando il seguente codice per mostrare un modulo come una finestra di dialogo modale.

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

devo fare questo perché ho una voce di menu per visualizzare il proposito di modulo nel menu del form principale, e nel menu contestuale dell'icona notifica.Se apro il modulo Informazioni tramite il menu del modulo principale, posso comunque aprire un'altra istanza utilizzando la voce di menu contestuale dell'icona di notifica.

Problemi correlati