2009-05-03 10 views
34

Ho sentito che se chiamo form.ShowDialog() senza specificare il proprietario, ci può essere un caso in cui non visualizzerò la finestra di dialogo sullo schermo (sarà nascosta con altre finestre). È vero? Ho usato ShowDialog() senza specificare il proprietario centinaia di volte e non ho mai avuto problemi con quello.Form.ShowDialog() o Form.ShowDialog (this)?

Potete spiegare in quale situazione posso ottenere il problema descritto?

UPDATE:

Beh, ho fatto molti esperimenti e non ho potuto ottenere qualsiasi veri problemi imprevisti con utilizzando ShowDialog() (senza specificare il proprietario).

Quindi penso che siano solo voci che ShowDialog() può portare a problemi. Se non sei d'accordo, dammi un esempio di codice per favore, questo porta a un problema.

+4

Questo non sembra applicarsi in Winforms, ma per la cronaca, sono venuto qui perché stavo avendo problemi in WPF. Se passassi a un'altra applicazione, quando ho cliccato di nuovo sul modulo genitore, la finestra di dialogo del bambino rimase bloccata (scocciatura dato che la finestra di dialogo del bambino era impostata per non apparire nella barra delle applicazioni). L'impostazione del proprietario della finestra di dialogo ha risolto questo problema. – Benjol

+4

Avvia un worker in background e chiama ShowDialog.La finestra non verrà visualizzata di fronte all'applicazione ma sullo sfondo (solo per infastidire i programmatori ciò accade solo di tanto in tanto). – CodingBarfield

+0

Barfieldmv, ho provato a fare quello che hai suggerito e il modulo appare in alto, non sullo sfondo. – nightcoder

risposta

6

solo per capire meglio il rapporto proprietario di proprietà:

NET consente una forma di “possedere” altre forme. I moduli di proprietà sono utili per la toolbox mobile e le finestre di comando . Un esempio di un modulo di proprietà è nella finestra Trova e sostituisci in Microsoft Word. Quando una finestra del proprietario è ridotta a , anche i moduli di proprietà vengono ridotti al minimo automaticamente. Quando un modulo di proprietà si sovrappone al proprietario, viene sempre visualizzato in primo piano.

(c) "Windows Form 2.0 Windows e controlli personalizzati" di Matthew MacDonald.


Come ShowDialog mostra la nuova forma, un relazione implicita è stabilito tra la forma attiva, noto come modulo proprietario , e la nuova forma, nota come la forma di proprietà. Questa relazione assicura che il modulo di proprietà sia il modulo attivo e sia sempre visualizzato su all'inizio del modulo proprietario.

Una caratteristica di questo rapporto è che la forma di proprietà influisce sul comportamento della sua forma proprietario (quando si utilizza ShowDialog):

  • Il modulo proprietario non può essere ridotto al minimo, massimizzata, o addirittura spostato.
  • Il modulo di proprietà blocca l'input del mouse e della tastiera nel modulo proprietario.
  • Il modulo proprietario è ridotto a icona quando il modulo di proprietà è.
  • Solo il modulo di proprietà può essere chiuso.
  • Se il proprietario e i moduli di proprietà sono ridotti a icona e se l'utente preme Alt + Tab per passare al modulo di proprietà, viene attivato il modulo di proprietà.

A differenza del metodo ShowDialog, però, una chiamata al Mostra metodo fa non stabilire un implicito rapporto proprietario di proprietà. Ciò significa che il modulo può essere il modulo attualmente attivo.

Senza una relazione implicita di proprietà del proprietario, i moduli proprietari e di proprietà possono essere ridotti a icona, ingranditi o spostati. Se l'utente chiude qualsiasi modulo diverso dal modulo principale, il modulo attivo più recente è riattivato.

Anche se ShowDialog stabilisce un implicito rapporto proprietario di proprietà, non c'è modo integrato per la forma di proprietà di richiamare alla o query la forma che aprì. Nel caso non modale, è possibile impostare la nuova proprietà Owner del modulo per stabilire la relazione di proprietà del proprietario. Come collegamento , è possibile passare il modulo proprietario come argomento a un sovraccarico del metodo Show, che accetta anche un parametro IWin32Window (IWin32Window viene implementato dagli oggetti UI Windows Form che espongono una proprietà HWND Win32 tramite IWin32Window. Gestire la proprietà).

Il comportamento delle forme in un esplicito modale proprietario di proprietà forma rapporto è lo stesso come la sua controparte modale implicita, ma la modale rapporto proprietario di proprietà fornisce un comportamento aggiuntivo nel caso non modale non-proprietario di proprietà. Innanzitutto, il modulo di proprietà non modale sempre viene visualizzato nella parte superiore del modulo proprietario, anche se entrambi possono essere attivi. È utile quando è necessario conservare un modulo, ad esempio una finestra mobile , sopra altri moduli all'interno di un'applicazione. In secondo luogo, se l'utente preme Alt + Tab per passare dal proprietario, i moduli di proprietà seguono la tuta . Per garantire che l'utente sappia quale modulo è il modulo principale, riduce al minimo il proprietario nasconde i pulsanti della barra delle attività per tutti i moduli di proprietà, lasciando visibile solo il pulsante della barra delle attività del proprietario.

(c) "Programmazione Windows Forms 2.0" di Chris Sells, Michael Weinhardt.

+0

Life saver, ora posso fare quello che mi serve – Takarii

+0

Splendida risposta dettagliata! –

5

Il parametro ShowDialog() utilizza semplicemente un parent "predefinito". Per quello che vale, il genitore predefinito è qualunque sia la "finestra attualmente attiva". Quando ti importa di cosa sia il genitore, devi impostarlo esplicitamente.

+0

Grazie, ma so che ShowDialog() utilizza una finestra attualmente attiva, ma non so come ci possa essere una situazione in cui la finestra di dialogo apparirà nel modo in cui l'utente non sarà in grado di vederla. – nightcoder

7

"Finestra attualmente attiva" si riferisce in genere alla finestra in primo piano, ma solo se appartiene al thread corrente - vedere GetActiveWindow in MSDN.

(Le informazioni effettive sono nel contenuto della community, ma il commentatore ha ragione che non esiste una "finestra attiva per thread", AFAIK).

Così, quando l'utente passa a un'altra finestra di applicazioni (o thread), si finisce con una "finestra di default". Anche se .NET fa un po 'di magia qui, la modalità verrà interrotta: la finestra genitore desiderata non verrà disabilitata (ad esempio, potresti passare alla finestra principale e chiuderla o modificare qualcosa, che spesso causa l'interruzione della tua applicazione a causa della rientranza) .

Inoltre, se un'altra applicazione è attualmente attiva, la finestra di dialogo non verrà visualizzata in alto, ma sarà nascosta dietro un'altra finestra.

Come piccola seccatura, la posizione iniziale è solitamente errata o fuorviante.

In pratica, ciò accade raramente, tuttavia: se si apre la finestra di dialogo in risposta a un menu o un pulsante, fare clic sulla finestra principale, l'utente non riuscirà praticamente mai a passare a un'altra finestra.

Tuttavia, è tecnicamente possibile, e molto probabile che accada se si apre la finestra di dialogo in risposta a qualche automatismo, messaggio esterno ecc

+5

Come regola generale, se è possibile specificare il genitore, è necessario specificare il genitore. Non fa mai male, e spesso aiuta. –

+0

In realtà ho questo problema - sto eseguendo un processo esterno da un plugin di Outlook - e non mostra la finestra di dialogo. Qualche idea su come mostrare il dialogo? Non ha alcuna forma -> voglio solo mostrare una finestra di dialogo. Se chiamo "MessageBox.Show" prima - funziona - altrimenti no. – bernhardrusch

+0

@bernhardrusch: Hai provato a specificare l'equivalente .NET di GetDesktopWindow come genitore? – peterchen

20

Un fastidio che ho trovato con ShowDialog() Vs ShowDialog (questo).

Eseguire la TestApp, mostrare il newform.ShowDialog(), fare clic su "Mostra desktop" sulla barra delle applicazioni o sulla barra degli strumenti Avvio rapido, fare clic su TestApp sulla barra delle applicazioni. Mostra la forma principale. Devi fare un Alt-Tab per arrivare al tuo nuovo modulo.

VS

Eseguire il TestApp, mostrare il newform.ShowDialog (questo), fai clic su "Mostra Desktop" sulla barra delle applicazioni o barra di avvio veloce, fare clic sul TestApp sulla barra delle applicazioni. Mostra la nuova forma in cima.

+0

Sto avendo esattamente il problema che descrivi. Ma ho cambiato ShowDialog() a ShowDialog (questo) e non ha aiutato. – Colin

1

Sì, in alcuni casi fa la differenza.Fino ad ora non ho avuto problemi con il metodo parametrico e sono rimasto un po 'sorpreso dal fatto che il modulo padre non fosse il modulo predefinito. Pertanto, per evitare comportamenti imprevisti, passare sempre il modulo genitore reale al metodo ShowDialog.

1

Prendiamo il seguente esempio:

Nel modulo principale, si dispone di un controllo ListView, con la modifica dell'etichetta abilitato. Quando un'etichetta specifica viene modificata, si avvia una seconda finestra (usando ShowDialog() in AfterLabelEdit). Il nuovo modulo non viene visualizzato nella barra delle applicazioni.

Se l'utente inizia a modificare l'etichetta, quindi fa clic su un'altra applicazione, quindi verrà visualizzato il secondo modulo, ma quando si torna alla propria applicazione all'utente verrà presentato solo il modulo principale, disabilitato poiché viene visualizzata una finestra di dialogo modale. Tuttavia, il solito meccanismo di intermittenza (che porta la finestra di dialogo modale al font se si fa clic sul chiamante) non funzionerà (sicuramente perché la chiamata di AfterEdit non è ancora stata restituita) e l'utente non sarà in grado di raggiungere il secondo modulo eccetto il ciclismo attraverso finestre aperte usando Ctrl + Tab.

La chiamata ShowDialog(this) risolve questo problema.

0

Ho avuto questo problema e per risolverlo, modificare la proprietà dello stato di Windows in modo normale, perché potrebbe essere ridotta a icona.

0

Ho appena trovato un caso in cui non specificare il proprietario utilizzando this ha causato un problema serio.

All'avvio la mia applicazione si impone di andare a schermo intero e si assicura anche che sia sempre attiva, anche se l'utente prova ad Alt + Tab di uscire da esso, a meno che non si acceda come amministratore o sviluppatore.

Quando uso ShowDialog() su un modulo personalizzato nella finestra di dialogo appare dietro la mia domanda per qualche ragione, e l'applicazione stessa non risponde perché la finestra di dialogo è attualmente attivo. Se utilizzo ShowDialog(this), il modulo si presenta come previsto.