Se si imposta SizeToContent
su WidthAndHeight
, quindi WindowStartupLocation="CenterOwner"
non funziona correttamente. Invece che il centro della nuova finestra si trova al centro del suo proprietario genitore, sembra più che l'angolo in alto a sinistra della finestra figlio sia al centro del genitore. Se rimuovo SizeToContent
allora tutto va bene. Cosa c'è che non va?finestra figlio wpf center non funzionante con sizetocontent
risposta
Quando una finestra viene mostrato, viene misurato, quindi WindowStartupLocation
viene elaborato utilizzando ActualWidth
e ActualHeight
della finestra calcolata dal processo di misura.
Il comportamento descritto mi dice che ActualWidth
e ActualHeight
sono misurati come zero o relativamente piccoli al momento della chiamata Show() o ShowDialog() e solo successivamente impostati su valori diversi da zero.
Ciò può accadere se, ad esempio, il contenuto della finestra viene creato utilizzando un DataContext impostato solo su un evento Loaded
. Quando si chiama Show()
, la finestra non è stata ancora Loaded
quindi non ha dati. Successivamente, quando viene attivato l'evento Loaded
, imposta DataContext e la finestra ne aggiorna il contenuto, ma il posizionamento è già presente.
Esistono molti altri scenari, ad esempio contenuti riempiti utilizzando una chiamata Dispatcher.BeginInvoke o da un thread separato o binding ritardati o asincroni.
Fondamentalmente è necessario cercare tutto ciò che potrebbe causare il contenuto della finestra per essere più piccolo del normale al momento si chiama Show()
e correggerlo.
La tua domanda è un po 'ambigua. Su quale finestra ("genitore" o "figlio") stai impostando SizeToContent e WindowStartupLocation?
Se creo una seconda finestra nel mio progetto e ne imposto SizeToContent e WindowStartupLocation nel modo in cui descrivi, ottengo i risultati desiderati.
L'unica cosa che posso pensare che si può essere dimenticando è quello di raccontare in realtà la finestra bambino che il suo proprietario è:
Window2 w = new Window2();
w.Owner = this; // "this" being the parent window
w.ShowDialog();
Oppure, più succintamente:
new Window2 { Owner = this }.ShowDialog();
Beh, Ray ha messo brillantemente questo. In termini semplici, quello che vuole dire è che si sta impostando il contenuto dei controlli nel vostro Loaded
evento, che resetta il Height
& Width
(e anche il ActualHeight
& ActualWidth
) dopo il posizionamento della finestra è fatto.
Per risolvere questo problema, si hanno due alternative:
- spostare il vostro codice di impostazione del valore dei contenuti al costruttore, o,
- Aggiungere un metodo semplice per ricalcolare la posizione del
Window
secondo ilOwner
e chiama questo metodo alla fine del tuo eventoLoaded
, in questo modo:
...
private void CenterOwner()
{
if (Owner != null)
{
double top = Owner.Top + ((Owner.Height - this.ActualHeight)/2);
double left = Owner.Left + ((Owner.Width - this.ActualWidth)/2);
this.Top = top < 0 ? 0 : top;
this.Left = left < 0 ? 0 : left;
}
}
Il contenuto dinamico associato è in gran parte reso Gui-direttamente ma a volte inviato tramite GUI. Timer e altri thread possono avviare eventi di modifica delle proprietà (MVVM). È certo, che il rendering viene eseguito in un tempo prossimo, ma non garantito, poiché posiziona una priorità della coda Dispatch di WPF. Quindi, non è possibile dire quando il rendering è finito, e WPF non può dire qualcosa sull'ordine di elaborazione, quindi WPF non può ora il momento ideale per calcolare la StartPosition.
Un trucco è, attendere, che la coda WPF sia emtpy. Allora sei sicuro che, WPF ha il tempo di elaborare il tuo codice. Ciò significa che si ritarda la chiamata ShowDialog per la finestra.
Quindi fornire il thread principale della GUI tutto il tempo necessario per, per eseguire le modifiche del contenuto dinamico per MVVM o altre modifiche dinamiche. Non provare a calcolare la posizione manualmente, è molto complesso, per supportare display multipli. Prova questo codice per aprire la finestra, apre solo la finestra, quando WPF ha completato tutte le operazioni.
win.Dispatcher.Invoke(new Action(() => win.ShowDialog()), DispatcherPriority.ApplicationIdle);
- 1. Determinare la dimensione della finestra WPF SizeToContent prima del rendering
- 2. Mantieni centrata la finestra dopo SizeToContent
- 3. Selettore primo figlio non funzionante
- 4. Stile finestra WPF non funzionante in fase di esecuzione
- 5. C# WPF - Black Line nella finestra
- 6. WPF: virtualizzazione TreeView non funzionante
- 7. : ultimo figlio in ng-repeat non funzionante
- 8. SizeToContent dipinge un bordo indesiderato
- 9. WPF: Center TabItems in un TabControl
- 10. Ricarica finestra padre dalla finestra figlio
- 11. Finestra del proprietario WPF nella parte superiore della finestra secondaria
- 12. WPF: impostazione DataContext di un UserControl con Binding non funzionante in XAML
- 13. PointerPressato non funzionante con clic sinistro
- 14. Chiusura finestra figlio minimizza genitore
- 15. C# WPF finestra trasparente con un bordo
- 16. Test di una finestra WPF con risorse statiche
- 17. finestra wpf interamente nera
- 18. Avere una finestra wpf all'interno di un'altra finestra wpf
- 19. Finestra di dialogo Winform con finestra WPF come genitore
- 20. text-align: center; non funziona
- 21. Come impostare ClientSize all'avvio della finestra WPF?
- 22. Finestra popup WPF
- 23. WPF Ottieni finestra principale
- 24. Fagiolo contrassegnato con ambito prototipo non funzionante in primavera
- 25. OpenID con Gerrit non funzionante
- 26. imagemagick con nodejs non funzionante
- 27. CABasicAnimazione non funzionante con UIImageView
- 28. text-align: center non funziona
- 29. Autenticazione GKLocalPlayer con Game Center
- 30. Come mantenere la dimensione della finestra WPF del contenuto con un Expander dopo il ridimensionamento
Grazie, stavo effettivamente caricando il contenuto subito dopo Show(). Errore stupido, funziona bene ora :) – immuner