2012-06-08 5 views
12

Ho bisogno di mostrare un modulo esattamente di fronte a un altro modulo, questo mi porta alla seguente domanda.Form.Parent e StartPosition.CenterParent

Come mai un modulo può avere una posizione di partenza come CenterParent mentre il campo this.Parent è uguale a null?

Deve conoscere il genitore per posizionarsi correttamente, cosa che fa, ma il campo Parent non è impostato. Questo è strano Mi sto perdendo qualcosa?

 Form2 f = new Form2(); 
     f.ShowDialog(); 

Questo è tutto ciò che faccio sul modulo figlio. Il genitore è impostato sulla posizione predefinita di Windows. Non importa dove sposto la forma genitore, il bambino è mostrato al centro del genitore.

+0

quando si avvia l'applicazione im indovinare il genitore che costerà un genitore è impostato al centro dello schermo in base a finestre ambienti naturali, se si sposta il presente modulo 'genitore' a dire l'angolo in alto a sinistra dello schermo, fa il "bambino" si trova ancora al centro o al centro dell'intero schermo? – RhysW

+0

Non importa dove sposto il modulo genitore, il bambino è possibilmente corretto – Odys

+1

quando si imposta il genitore come null? il centraggio viene eseguito nell'evento onload, se si imposta il suo genitore su null al di fuori di questo potrebbe essere il motivo. ha un genitore, centri, poi ha detto che non ha un genitore dopo la domanda modificata – RhysW

risposta

8

Le informazioni sul proprietario viene passato alla finestra di dialogo creato tramite la chiamata API (si può vedere che in Reflector all'interno del ShowDialog (IWin32Window proprietario) metodo):

UnsafeNativeMethods.SetWindowLong(new HandleRef(this, base.Handle), -8, new HandleRef(owner, handle)); 

quando non c'è proprietario specificato in showDialog chiamare la variabile owner è calcualated tramite la chiamata API GetActiveWindow:

IntPtr activeWindow = UnsafeNativeMethods.GetActiveWindow(); 
IntPtr handle = (owner == null) ? activeWindow : Control.GetSafeHandle(owner); 

per ottenere l'accesso al proprietario f modulo finestra di dialogo è possibile utilizzare il GetWindowLong API call:

IntPtr ownerHandle = NativeMethods.GetWindowLong(nonModalForm.Handle, -8); 
+0

Grazie DmitryG, ma qual è la magia che succede con 'ShowModal'? Nota che non passo il genitore a 'ShowDialog()' però. – Odys

+0

+1 Buon punto. –

+0

Questa versione del metodo ShowDialog non specifica un modulo o un controllo come proprietario. Quando viene chiamata questa versione, la finestra attualmente attiva diventa il proprietario della finestra di dialogo. Se si desidera specificare un proprietario specifico, utilizzare l'altra versione di questo metodo. Leggi i commenti MSDN - http://msdn.microsoft.com/en-us/library/c7ykbedk.aspx. Penso che tu possa accettare la risposta di DmitryG. –

1

Credo che questa informazione sia archiviata internamente da .NET Framework per qualche motivo. In ogni caso, se si vuole avere accesso al modulo genitore è possibile impostarlo Owner property del form figlio:

Form form = new Form(); 
form.Owner = this; 
form.Show(); 

Poi nel bambino modulo è possibile accedere al form padre utilizzando la proprietà del proprietario. Quando un modulo è di proprietà di un altro modulo, viene ridotto a icona e chiuso con il modulo proprietario. Anche i moduli di proprietà non vengono mai visualizzati dietro la loro forma di proprietario, il che è esattamente ciò di cui hai bisogno se ti capisco bene.

3

La differenza tra un genitore e un proprietario di una finestra è un po 'confusa in Winforms. In questo contesto, CenterParent significa davvero CenterOwner. Non è una funzionalità di Windows, è implementato in Winforms, fatto dal metodo base Form.OnLoad(). Una finestra di dialogo dovrebbe sempre avere un proprietario, esce cercandone uno quando non ne specifichi uno nella chiamata ShowDialog(). Che utilizza GetActiveWindow() come la migliore ipotesi.

Per vedere questo per te, sovraccarico OnLoad in forma di dialogo, in questo modo:

public partial class Form2 : Form { 
    public Form2() { 
     InitializeComponent(); 
     this.StartPosition = FormStartPosition.CenterParent; 
    } 
    protected override void OnLoad(EventArgs e) { 
     //base.OnLoad(e); 
    } 
} 

e si noti che non è più incentrata sul proprietario.

potete vedere il relativo codice nel sorgente di riferimento, la classe Form.cs, metodo OnLoad:

if (GetState(STATE_MODAL)) { 
    FormStartPosition startPos = (FormStartPosition)formState[FormStateStartPos]; 
    if (startPos == FormStartPosition.CenterParent) { 
     CenterToParent(); 
    } 
    else if (startPos == FormStartPosition.CenterScreen) { 
     CenterToScreen(); 
    } 
} 
0

Questo codice si aprirà la finestra di dialogo al centro del TAG genitore.

ObjectDistrubution od = new ObjectDistrubution(); 
    od.StartPosition = FormStartPosition.CenterParent; 
    od.ShowDialog();