Question

Comment puis-je forcer ShowDialog à revenir d'un fil d'arrière-plan?

J'ai une application WPF construit au-dessus d'un cadre de C ++ / CLR qui écoute les messages envoyés par le cadre. Un message particulier est si important que je dois fermer toutes les fenêtres actuelles. Toutefois, si un Dialog modal (créé par ShowDialog de ma fenêtre principale) est actif et en attente de l'entrée d'utilisateur, la fenêtre ne se fermera pas parce qu'il attend ShowDialog pour revenir. Comment puis-je forcer le Dialog modal pour fermer et détendre l'exécution de code?

J'ai essayé le réglage de la DialogResult ou en appelant Close mais qui ne semble pas fonctionner.

Edit: Le Dialog est créé par ma fenêtre principale qui attend une valeur de retour, comme ceci: (À l'intérieur d'un gestionnaire d'événement de clic en MainWindow):

Window modalDialog = new Window();
bool ret = (bool)modalDialog.ShowDialog();
if (ret == true)
{
 // do stuff
}
else
{
 // do some other stuff
}

Lorsque le cadre envoie un message (à venir sur un autre thread que le thread d'interface utilisateur), je l'appelle MainWindow.Close(). La boîte de dialogue modale se ferme à ce stade, mais le code de vérification de la valeur de retour de la Dialog (après ShowDialog) est toujours sur la pile. D'une certaine manière cela force la fenêtre principale de ne pas disparaître.

Était-ce utile?

La solution

Lorsque la boîte de dialogue reçoit le message WM_CLOSE il définit un indicateur qui provoque ShowDialog pour revenir après la WM_CLOSE et les messages contenant ont été entièrement traitées. Donc, si vous faites un Dispatcher.Invoke() sur votre fil pour appeler MainWindow.Close(), le ShowDialog() ne reviendra qu'après la Dispatcher.Invoke() terminée.

Donc, la solution simple est de retour de la Dispatcher.Invoke() pour obtenir le ShowDialog() pour revenir. Si plus le traitement est nécessaire, faire une autre Dispatcher.Invoke() immédiatement après.

Si vous faites la transition de fil d'une autre manière que Dispatcher.Invoke(), ou si le ShowDialog() ne revient pas après le retour d'appel Dispatcher.Invoke (), vous pouvez avoir à poster une partie du code entourant votre appel Window.Close() afin que nous puissions voir ce que vous faites réellement.

Autres conseils

Vous ne pouvez pas forcer ShowDialog à revenir, mais vous pouvez avoir la fenêtre écouter un événement envoyé par votre cadre qui peut lui dire de fermer. Dans l'exemple ci-dessous événement Progress a une « Terminé » le drapeau ferme la fenêtre lorsque vous avez terminé.

SomeGenerator IG = Manager.SomeGenerator();
SomeWindow PP = new SomeWindow();
IG.ProgressEvent += PP.ProgressEvent;
IG.ExecuteAsync();            
PP.ShowDialog();

Je me rends compte maintenant que je ne peux pas forcer ShowDialog à revenir et continuer l'exécution chaque fois que je veux. Le gestionnaire d'événements pour la demande que je reçois des besoins cadres sortir du contexte de sorte que la pile d'appel peut être dénoué et la boîte de dialogue modale peut traiter le message Fermer.

J'ai fini par mettre un drapeau booléen, demandant modaux fermer, puis revenir de mon gestionnaire d'événements-cadre. Seulement à ce moment sera showDialog retour et je peux vérifier pour le drapeau que je mets et poursuivre l'action demandée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top