Pourquoi utiliser un propriétaire fenêtre MessageBox.Spectacle?
MessageBox.Spectacle a la forme de la MessageBox.Show( ownerWindow, .... ).
Que dois-je gagner par l'attribution d'une fenêtre propriétaire?
Vous devez vous connecter pour publier un commentaire.
Une boîte de message est un formulaire modal, ce qui signifie que son parent de la fenêtre est désactivée jusqu'à ce que la boîte de message est rejeté.
Si un Show() de surcharge est appelé à ne pas prendre un propriétaire identifiant, puis un formulaire parent est généralement choisi automatiquement. Je ne peux pas trouver quelque chose dans la documentation qui décrit comment la forme choisie, mais mon expérience est que si la boîte de message est affiché à l'intérieur de la thread GUI (c'est à dire, le thread principal, ou un message de la pompe fil), puis la fenêtre active pour que le thread est choisi en tant que parent.
D'autres threads peuvent créer des boîtes de message avec aucun parent ne forme. Cela pourrait être une mauvaise situation, car il pourrait s'asseoir derrière la fenêtre active, et l'utilisateur ne saura même pas qu'il est là jusqu'à ce qu'ils fermer le programme. Pour éviter cela, vous pourriez passer le handle de la fenêtre principale de l'application de la méthode Afficher, désactiver cette fenêtre pour la durée de la boîte de message.
AJOUTÉ: j'ai pensé à ce sujet et maintenant, je ne suis pas si sûr. L'extrait de réflecteur que vous avez donné ci-dessous me fait penser que peut-être le fil n'a pas d'importance. (J'ai dit que je ne pouvais pas trouver quoi que ce soit dans la documentation!)
Je dois revenir en arrière et regarder le code pour être sûr, mais je pense que les boîtes de message que j'ai utilisé pour perdre derrière la principale forme ont été effectivement boîte de message personnalisée formes, auquel cas mon expérience est défectueux, et vous ne jamais avoir à fournir un formulaire parent paramètre.
Désolé pour la confusion.
Ma recommandation est maintenant de ne jamais alimenter ce paramètre, sauf si vous avez besoin d'autre chose que de la fenêtre active à l'écran principal.
MessageBox
être modale, de s'assurer qu'elle est appelée à partir d'uneInvoke()
sur leForm
il doit être modal. Si vous trouvez que vous avez réellement besoin d'Invoke()
, assurez-vous de passer chez le propriétaire. (Ainsi, par exemple, il n'est pas nécessaire de spécifierowner
ouInvoke()
lors de l'appel deMessageBox.Show()
dans un boutonClick
gestionnaire d'événement).Réglage de la propriétaire provoque le propriétaire pour handicapés, tandis que la boîte de message est ouvert.
Si vous ne définissez pas le propriétaire, alors l'utilisateur peut cliquer sur autre chose, ou même à proximité du propriétaire, tandis que la boîte de message est ouvert, puis quand la boîte de dialogue se ferme et le code après l'appel à la MessageBox.Montrer exécute votre programme peut être dans un état inconnu ou si le propriétaire a été fermé vous êtes maintenant en cours d'exécution de code à l'intérieur d'une fenêtre qui n'existe plus et tous les appels à des méthodes de WinForms ou WPF (ou, d'ailleurs, aussi WinAPI et n'importe quel autre framework) sont susceptibles de provoquer un accident.
Basé sur des tests et cette autre réponse, .net choisira automatiquement l'concentre actuellement de la fenêtre dans le même fil que votre
MessageBox.Show()
appel. Pour obtenir le comportement correct, vous doit assurer que vous affichez laMessageBox
de la même thread que cette fenêtre et spécifier la fenêtre de laMessageBox
est logiquement associée avec commeowner
. UnMessageBox
seulement modal-ly blocs d'entrée à d'autresForm
s sur le fil à partir de laquelle il est lancé. Ceci est probablement lié à la façon dontMessageBox
se fait modal (peut-être qu'il intercepte les messages visant à le thread en cours et ne permet que des messages par le biais de windows autres que lui-même?). L'effet de modal-ly le blocage de l'entrée, c'est que l'utilisateur sera incapable de se concentrer ces fenêtres ou les contrôles à l'intérieur d'eux et d'essayer de le faire produit le "Ding" du son. Aussi, si le propriétaire n'est pas spécifié, laMessageBox
permet de sélectionner automatiquement la fenêtre active sur le thread courant. Si la fenêtre active est à partir d'un autre thread (ou autre application!), leMessageBox
aura pas de propriétaire. Cela signifie qu'il dispose de sa propre Barre de Tâches de l'entrée: il se comporte comme son propre fenêtre. L'utilisateur peut soulever d'autres fenêtres de votre application (même si l'utilisateur ne peut pas interagir avec eux). Vous pouvez obtenir le situation où votre programme cesse de répondre à la saisie de l'utilisateur avec l'utilisateur confus parce que l'utilisateur en quelque sorte élevé votre fenêtre principale de l'application après la boîte de dialogue est affichée. Si le propriétaire est correctement réglé, cependant, essayez d'augmenter votre fenêtre principale sera la cause de laMessageBox
être soulevées et cligna des yeux.De faire tout cela fonctionne très bien avec les enfants de windows, de s'assurer que chaque enfant fenêtre a son
Propriétaire
ensemble de propriétés. Cela se fera automatiquement si vous appelezShowDialog()
(ce qui rend votre personnaliséForm
modal (et ne passer sonowner
paramètre dans les mêmes cas où vous passerez desowner
àMessageBox.Show()
)).Maintenant, la plupart des winforms de codage consiste à écrire le code directement dans les gestionnaires d'événements à l'intérieur d'un
Form
sous-classe. Lors de l'écriture de winforms gestionnaires d'événements, vous pouvez supposer beaucoup de choses. Tout d'abord, vous ne devriez jamais avoir un appel à l'this.Invoke()
comme un haut niveau d'instruction dans une interface graphique du gestionnaire d'événement parce que ces gestionnaires sont toujours exécuter sur le même thread que l'Form
sous-classe est créée. Deuxièmement, pour de nombreux (mais pas tous) de ces gestionnaires, vous pouvez supposer que leForm
a le focus (et serait donc automatiquement choisi parMessageBox.Show()
que son propriétaire). Par exemple, lors de l'écriture de code à l'intérieur de l'événement Click d'un bouton gestionnaire (probablement appelébutton1_Click
), vous pouvez supposer que la forme est concentré (parce que l'appel dePerformClick()
sur un autre formulaireButton
est une mauvaise pratique). Cependant, unMinuterie.Tique
peut se produire même si votre formulaire n'est pas concentré. Ainsi, dans le cas deTimer.Tick
, il est pas besoin deInvoke()
(comme tous les autres winforms gestionnaire d'événement) mais il y est un besoin de spécifierowner
. Ce dernier cas est plus difficile à percevoir, car le développeur doit avoir leur application floue noter qu'une boîte de dialogue s'affiche, dans ce cas, se comporte légèrement différemment lorsque leur application est concentré. Donc, spécifierowner
chaque fois que vous devez utiliserInvoke()
ou si c'est possible pour que l'événement puisse être déclenché lorsque la fenêtre ne se concentre pas. Cette directive s'applique lors de l'appel deMessageBox.Show()
etForm.ShowDialog()
.La plupart de ce que je discute ici est le résultat de déconner lors de la lecture d'autres réponses.
Il s'avère que la fenêtre de propriété n'est pas transitive. Dans le cas où vous avez la forme, la ponte d'un formulaire, la ponte d'une MessageBox, La MessageBox.Spectacle doit utiliser le ownerWindow paramètre. Le formulaire original doit être définie en tant que propriétaire de la fenêtre MessageBox.
Show()
ouShowDialog()
sur ses donné naissance à la forme? Je vais devinerShow()
parce que quand j'essaie de le parent d'un formulaire imbriqué lancé viaShowDialog()
qui possède unMessageBox
, Windows génère automatiquement le parent, imbriqué, etMessageBox
et clignote leMessageBox
pour moi de façon appropriée.Appel
MessageBox.Show(frmMain,"a message","a title")
ajoute le formulaireTextDialog
pour l'application du
Application.OpenForms()
collection de formulaires, aux côtés de la frmMain formulaire Principal lui-même. Il reste après la fermeture de la Messagebox.Je viens de découvrir 14 de ces quand j'ai appelé
btnOK_Click()
et définir un point d'arrêt.Quand j'ai appelé
frmMain.Close()
pour fermer le formulaire, rien ne s'est passé. frmMain ne se ferme pas jusqu'à ce que tous 14 de l'Application.OpenForms sont fermés aussi bien ou alors vous devez appelerApplication.Exit()
.si je ne me trompe pas cela empêche le propriétaire de la fenêtre pour le Focus() jusqu'à ce que la messagebox est fermé.
MessageBox
’s “propriétaire”.À l'aide de Net Réflecteur, je viens de trouver ce code dans Messagebox.Spectacle:
Donc, si vous n'avez pas imbriquée à la propriété ( fenêtre--(possède)-->fenêtre--(propriétaire)->messageBox), en laissant de côté la ownerWindow définit le propriétaire vous le feriez normalement choisir.
La documentation semble impliquer que le seul but de la propriétaire paramètre si vous spécifiez MB_HELP, la boîte de message sait la fenêtre dans laquelle il faut envoyer le message WM_HELP à.
http://msdn.microsoft.com/en-us/library/ms645505%28VS.85%29.aspx
Oh, viens de réaliser que l'OP était d'environ .net - j'ai donné une réponse à ce sujet winapi - désolé!