Suggestions pour un remplacement de MessageBox.Show qui ne bloque pas le thread d'interface graphique?

StackOverflow https://stackoverflow.com/questions/198868

  •  11-07-2019
  •  | 
  •  

Question

Il y a quelque temps, je me suis heurté à une situation dans laquelle nous devions afficher des boîtes de message à l'utilisateur pour les notifications, mais nous ne pouvions pas utiliser MessageBox.Show, car il bloque le fil de l'interface graphique (de sorte que rien ne soit mis à jour à l'écran pendant le dialogue. actif). Des suggestions sur une alternative?

[J'ai codé une alternative à l'époque mais je ne l'aime pas. Je vais le poster comme une réponse si rien ne semble mieux cependant]

EDIT: le dialogue doit flotter en haut de la fenêtre principale; Je ne me soucie pas si cela apparaît dans la barre des tâches ou non. Plusieurs boîtes de dialogue peuvent être actives à la fois dans certaines circonstances.

ADDENDUM: ma solution était un formulaire de base qui fournissait les boutons OK et ANNULER pour émettre les événements Terminé et Annulé; OK a appelé une validation virtuelle ValidateData pour la substitution de sous-classe. Le formulaire appelant utilisait des propriétés pour éviter de recréer le formulaire à chaque fois (le formulaire était simplement masqué au lieu de fermé) et conservait un dictionnaire de formulaires actifs pour empêcher le même formulaire de s'activer plusieurs fois. Cela ressemble à un formulaire modal, prend en charge plusieurs formulaires en même temps, mais n'attache pas le fil principal de l'interface graphique.

Était-ce utile?

La solution

Je suis d’accord avec rslite et Mitchel Sellers. La meilleure voie à suivre consiste à créer un formulaire non modal pour afficher les informations nécessaires. Si vous avez plusieurs messages, vous pouvez envisager de les insérer dans un contrôle ListBox et demander à l'utilisateur de double-cliquer dessus pour obtenir les informations complètes à afficher.

Autres conseils

Je suggère d’adopter une approche non modale, comme d’autres, mais un peu plus précise:

  • Si vous souhaitez simplement recevoir une notification, vous pouvez essayer une info-bulle (la TNA ou la vôtre), ou une fenêtre semblable à la notification de messagerie Outlook ou à la notification de nombreux messagers instantanés tels que l'affichage Trillian.
  • Si vous voulez simplement donner à l'utilisateur une chance d'agir, utilisez un formulaire non modal, mais souvenez-vous qu'il peut très bien cliquer dessus.
  • Si l'utilisateur DOIT donner suite à votre message, vous devriez aller en mode modal. Notez que la fenêtre du propriétaire sera toujours peinte et que vous pourrez actualiser votre interface graphique - une boîte de dialogue modale, après tout, contient une pompe à message, sinon elle ne fonctionnerait pas. J'ai fait quelque chose comme ça récemment, nous avions un pool de threads de travail d'arrière-plan qui pouvait mener toutes les actions et événements au feu pour l'actualisation de l'interface graphique, ainsi qu'une boîte de dialogue d'attente modale qui contenait toujours son message. La fenêtre propriétaire a été mise à jour avec l'action en arrière-plan comme prévu.

Pourquoi ne pas ajouter un NotifyIcon ? dans votre application et en affichant un info-bulle . L’inconvénient est que la notification disparaîtra au bout de peu de temps, mais c’est peut-être mieux pour vos utilisateurs s’ils n’ont pas besoin d’agir.

Je résoudrais cela en utilisant une boîte de dialogue non modale ou peut-être des info-bulles en fonction des besoins spécifiques.

Si vous ne voulez pas le bloquer, je créerais simplement votre propre formulaire simple pour faire l'affichage. C’est ainsi que j’ai complété les éléments pour les clients auparavant, quand une solution non bloquante était nécessaire. Mais gardez à l’esprit que si vous le faites de manière non bloquante, les utilisateurs risquent d’obtenir des multiples et d’être dépassés s’ils sont réellement "vous devez agir". tapez des éléments.

merci à tous ceux qui ont fait des suggestions, il semble que ma solution était à peu près correcte ;-)

ma solution était un formulaire de base fournissant des boutons OK et ANNULER pour émettre des événements Terminé et Annulé; OK a appelé une validation virtuelle ValidateData pour la substitution de sous-classe. Le formulaire appelant utilisait des propriétés pour éviter de recréer le formulaire à chaque fois (le formulaire était simplement masqué au lieu de fermé) et conservait un dictionnaire de formulaires actifs pour empêcher le même formulaire de s'activer plusieurs fois. Cela ressemble à un formulaire modal, prend en charge plusieurs formulaires en même temps, mais n'attache pas le fil principal de l'interface graphique.

Si vous souhaitez que l'apparence de la MessageBox soit visible, affichez-le simplement dans un fil d'arrière-plan.

ThreadPool.QueueUserWorkItem( (state) =>
    {
         MessageBox.Show("Your message");
    });

(code non testé)

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