10
votes

WPF Center Fenêtre enfant ne fonctionne pas avec sizétocontent

si je définis sizétocontent sur widthanandheight , alors windowstartuplocation = "Centre-propriétaire" ne fonctionne pas correctement. Au lieu du centre de la nouvelle fenêtre pour être au centre de son propriétaire parent, cela ressemble plus au coin supérieur gauche de la fenêtre de l'enfant au centre du parent. Si je supprimai sizetocontent alors tout va bien. Qu'est-ce qui ne va pas?


0 commentaires

4 Réponses :


1
votes

Votre question est un peu ambiguë. Sur quelle fenêtre (le «parent» ou «enfant» ou «enfant») définissez-vous sizétocontent et windowstartuplocation?

Si je crée une deuxième fenêtre dans mon projet et définissez son sizétocontent et votre windowstartuplocation comme vous le décrivez, je reçois les résultats souhaités.

La seule chose que je peux penser à ce que vous puissiez oublier, c'est de dire à la fenêtre de l'enfant que son propriétaire est: xxx

ou, plus succinctement : xxx


0 commentaires

6
votes

Lorsqu'une fenêtre est affichée, il est mesuré, alors windowstartuplocalisation est traité à l'aide du réelWidth et actuelheight de la fenêtre calculée par la mesure processus.

Le comportement que vous décrivez me dit réelWidth et actuelHeight est mesuré pour être égal à zéro ou relativement petit au moment de l'appel de spectacle () ou de ShowDialog () et uniquement plus tard réglé sur les valeurs non nulles.

Cela peut arriver si, par exemple, le contenu de la fenêtre est construit à l'aide d'un DataContext uniquement défini sur un événement . Lorsque le Afficher () est appelé, la fenêtre n'a pas été chargée pour la fois qu'il n'a pas de données. Plus tard, lorsque les incendies d'événement Chargé définissent DataContext et la fenêtre met à jour son contenu, mais le positionnement est déjà survenu.

Il existe de nombreux autres scénarios, par exemple des contenus remplis à l'aide d'un appel Dispatcher.BeginInvoke ou d'un fil séparé, ou des fixations retardées ou asynchrones.

Fondamentalement, vous devez rechercher tout ce qui pourrait entraîner une plus petite quantité que la normale que la normale au moment où show () est appelé et corrigez-le.


1 commentaires

Merci, je chargeais réellement le contenu juste après le spectacle (). Erreur stupide, fonctionne bien maintenant :)



9
votes

Eh bien, Ray a mis ce problème brillamment. En termes simples, ce qu'il veut dire, c'est que vous définissez le contenu de vos commandes dans votre événement chargé , qui réinitialise la hauteur & largeur (et aussi le réticalHeight & réelWidth ) Après le positionnement de la fenêtre est effectué.

Pour résoudre ce problème, vous avez deux alternatives: < ol>

  • Déplacez votre code de réglage de la valeur de contenu sur le constructeur ou,
  • Ajoutez une méthode simple pour recalculer la position de votre fenêtre en fonction du propriétaire et appelez cette méthode à la fin de votre chargé événement , comme ceci:

    ... xxx


  • 0 commentaires

    3
    votes

    Le contenu dynamique contraigné est surtout rendu GUI-directement mais parfois enregistré par l'interface graphique. Minuterie et autres threads peuvent initier des événements de changement de propriété (MVVM). Il est sûr que le rendu est effectué dans une quasi-temps, mais non garanté, car positionnez une priorité de la file d'attente de la dispicatrice WPF. Donc, vous ne pouvez pas dire que lorsque le rendu est terminé et que WPF ne peut pas dire quelque chose à propos de l'ordre de traitement - de sorte que WPF ne peut donc pas maintenant le moment idéal pour calculer la découverte.

    Un truc est, attendre que la file d'attente WPF est Emtpy. Ensuite, vous êtes sûr que WPF a le temps de traiter votre code. Cela signifie que vous retardez l'appel de ShowDialog pour la fenêtre. P>

    Donnez au fil de l'interface graphique tout le temps qu'il a besoin strong>, pour effectuer les modifications de contenu dynamiques pour MVVM ou d'autres modifications de dynamique. N'essayez pas de calculer la position manuellement, il est très complexe, de prendre en charge plusieurs écrans. Essayez ce code pour ouvrir la fenêtre, il ouvre la fenêtre uniquement lorsque WPF a terminé toutes les opérations for forte>. P>

            win.Dispatcher.Invoke(new Action(() => win.ShowDialog()), DispatcherPriority.ApplicationIdle);
    


    0 commentaires