Partage
  • Partager sur Facebook
  • Partager sur Twitter

Shutdown mode for WPF and forms

Sujet résolu
    4 janvier 2022 à 14:52:22

    Salut,

    J'ai une application qui affiche tantôt des fenêtres en WPF tantôt en windows Forms (à l'origine l'application était en win Form, mais migre doucement en WPF).


    Je souhaiterais que lorsque toutes les fenêtres sont fermées, l'application s'arrête (shutdown mode= last window close), mais ce n'est pas le cas.
    Si le projet de démarrage est en WPF, l'application s'arrête lorsque la dernière fenêtre WPF est fermée (même si des win Forms sont encore ouvertes), et vice et versa avec un projet de démarrage en Win Form.

    Je sais qu'il est possible d'arrêter l'application via le code (en changeant le shutdown mode), mais ça me parait pas idéal à gérer... il faudrait que je vérifie si une fenêtre n'est pas ouverte à chaque fois qu'une ne se ferme...

    N'y aurait-il pas une solution pour redéfinir la méthode qui détermine que la dernière fenêtre est fermée?

    Merci pour votre aide :)

    • Partager sur Facebook
    • Partager sur Twitter
      4 janvier 2022 à 18:12:18

      >la méthode qui détermine que la dernière fenêtre est fermée?

      Je ne crois pas que cela soit une "méthode".

      Pourquoi ne pas avoir un "WindowsManager", soit un 'WindowsManager" dérivant de WinFrom pour le cas "démarrage WinForm", soit un "WindowsManager" compliant WPF pour l'autre cas ?

      Ce "WindowsManager" serait la tour de contrôle des fenêtres du type opposé au "type de démarrage".

      Il serait alors à même de savoir combien de fenêtres "Alien" existe encore. Si au moins une fenêtre alien existe, il générera une fenêtre fantôme "terrestre" pour ne pas fermer l'application par "inadvertance".

      Mais bon, une application où on est obligé de fermer toutes les fenêtres pour sortir, bofbof.

      • Partager sur Facebook
      • Partager sur Twitter
      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
        4 janvier 2022 à 18:55:50

        Salut,


        Merci pour ta réponse :).


        >Mais bon, une application où on est obligé de fermer toutes les fenêtres pour sortir, bofbof.
        Même si cela n'est pas vraiment ça, tu peux voir l'appli comme un explorateur de fichier, quand tu ouvres une nouvelle fenêtre, tu ne voudrais pas qu'elle se ferme lorsqu'une autre est fermée ;) (tu me diras, mais dans ce cas, tu pourrais ouvrir une nouvelle instance de l'appli pour chaque fenêtre, mais là n'est pas la question..).

        >Pourquoi ne pas avoir un "WindowsManager", soit un 'WindowsManager" dérivant de WinFrom pour le cas "démarrage WinForm", soit un "WindowsManager" compliant WPF pour l'autre cas ?
        Ca voudrait dire qu'à chaque fois qu'une fenêtre est ouverte, ou fermée, je dois appeler une méthode de ce manager depuis le "onLoad" et "onClosed" de la fenêtre? c'est bien ca?
        J'aurais préféré une solution un peu plus "automatique", de plus, certaines fenêtres sont ouvertes via l'appel de méthode d'assembly sur lesquelles je n'ai pas forcément la main...

        • Partager sur Facebook
        • Partager sur Twitter
          4 janvier 2022 à 19:20:48

          >tu pourrais ouvrir une nouvelle instance de l'appli pour chaque fenêtre, mais là n'est pas la question.

          Bin si, c'est même comme ça que fonctionne l'explorateur Windows : multi-instance, et c'est logique pour l'utilisateur de l'application.

          Je ne connais pas ta démarche ergonomique mais depuis ma fenêtre, c'est un non-sens.

          Je suis peut-être un vieux con-boomer, mais si j'ai une application avec des fenêtres "volantes" tout autour des moniteurs, j'aimerai bien, au minimum, disposer d'une fenêtre "principale" avec un menu qui liste les "fenêtres/vues" encore ouvertes, de faire des arrangement "automatiques" de celles-ci, etc... (et quand on la ferme, c'est la fin de l'application, donc des fenêtres "flottantes")

          Cela me fait penser que la technique habituelle pour ce type de transition technologique, c'est le "Hosting" de composant graphique.

          https://docs.microsoft.com/fr-fr/dotnet/desktop/wpf/advanced/walkthrough-hosting-a-windows-forms-control-in-wpf?view=netframeworkdesktop-4.8

          En gros, on encapsule les vieux machins (ici, les composants WinForm) dans un composant (le host) du nouveau framework, ici WPF, pour que le nouveau framework voit l'antiquité comme un composant "normal".

          -
          Edité par bacelar 4 janvier 2022 à 19:22:18

          • Partager sur Facebook
          • Partager sur Twitter
          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
            4 janvier 2022 à 20:30:28

            Je comprends la réflexion sur le multi instance, et la gestion avec une fenêtre principale, mais comme je t'ai dit, c'est pas la question (trop de change utilisateur/dev...).

            Le hosting, je connais dans le sens form qui Host wpf usercontrol, ça marche..., c'est bien, mais c'est pas top non plus (de tête, gestion des shadow effect sur les bords de la fenêtre foireuse).

            La meilleure solution que j'ai en tête, c'est de basculer en shutdown mode par le code, et déclencher un timer toutes les x secondes pour checker si une fenêtre est ouverte (sur Application.OpenForms pour les forms). 

            Mais je me demande quand même si on pourrait pas capturer un event sur l'ouverture/fermeture d'une fenêtre au niveau de l'appli (du style, capturer l'événement d'ajout sur la collection Application.OpenForms)

            • Partager sur Facebook
            • Partager sur Twitter
              6 janvier 2022 à 14:28:31

              >Le hosting,...(de tête, gestion des shadow effect sur les bords de la fenêtre foireuse).

              Pour une étape "intermédiaire", des shadows effects qui fonctionnent mal, c'est vraiment pas grave et on peut toujours "gruger" pour que ces limitations ne se voient pas.

              Je trouve que la solution que vous envisagez n'est vraiment pas bonne.

              Ce que je propose moi, avec des "WindowsManager", c'est que toutes les fenêtres "aliens" soient créées par ce manager et qu'il sert d'ancre pour la non fermeture tant que toutes les fenêtres "aliens" ne sont pas fermées.

              • Partager sur Facebook
              • Partager sur Twitter
              Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                6 janvier 2022 à 15:24:58

                Par rapport au hosting, je ne dis pas le contraire, j'ai écrit "c'est pas top non plus", j'aurais plutôt dû écrire "c'est pas parfait non plus".
                Et je suis d'accord que ce n'est pas grave, ou indispensable, mais c'est un atout (comme bien d'autres évidement) pour justifier les changements de techno.

                >Je trouve que la solution que vous envisagez n'est vraiment pas bonne.
                Vous pouvez expliciter SVP? j'ai parlé de timer, mais cela pourrait bien être une simple boucle asynchrone avec un task.delay (avec pourquoi pas, l'utilisation de la fenêtre fantôme dont vous parliez).
                Idéalement, j'aurais préféré capturer un event "standard" de fermeture de fenêtre.

                >Ce que je propose moi, avec des "WindowsManager", c'est que toutes les fenêtres "aliens" soient créées par ce manager et qu'il sert d'ancre pour la non fermeture tant que toutes les fenêtres "aliens" ne sont pas fermées.

                Si le besoin concerne une nouvelle application en partant de 0 effectivement, cela me semble être une solution intéressante.

                Là, il s'agit d'une transition temporaire pour une application qui est aujourd'hui très utilisée.

                Comme écrit plus haut, certaines fenêtres s'ouvrent par l'appel de service sur des assembly sur lesquelles je n'ai pas forcément la main (ou partagées avec d'autres projets qui fonctionnent différemment). => Mais peu importe, la seule chose à retenir, c'est que je ne pourrais pas passer par le manager pour l'ouverture de toutes les fenêtres.

                J'essaie juste de trouver une solution pour reproduire le comportement standard du "shutdown mode = last window close" (dans un contexte hétérogène) dont je suppose ne pas être le seul à utiliser...

                • Partager sur Facebook
                • Partager sur Twitter
                  6 janvier 2022 à 19:34:12

                  >Vous pouvez expliciter SVP? j'ai parlé de timer, mais cela pourrait bien être une simple boucle asynchrone

                  Bin, c'est bien ça qui me fait tiquer, les aspects asynchrones qui complexifient tous, en particulier quand on doit plier les gaules en bon ordre.

                  >Idéalement, j'aurais préféré capturer un event "standard" de fermeture de fenêtre.

                  Normalement, c'est les framework de "hosting" qui se chargent de toute cette tuyauterie ainsi que le gestion d'ouverture d'autres fenêtres depuis la fenêtre hosté, et c'est le genre de truc qui est loin d'être une sinécure car il faut un très bon niveau dans les frameworks hostés/hostants et souvent du système d'exploitation.

                  >Là, il s'agit d'une transition temporaire pour une application

                  Oui, mais pour une application avec un minimum d’envergure, la partie IHM est totalement dé-corrélée du reste de l'application et donc les mécanismes de création d'IHM devraient déjà passer par l'utilisation de Design Pattern de création. Donc ça serait juste customiser le Design Pattern utilisé.

                  >certaines fenêtres s'ouvrent par l'appel de service sur des assembly sur lesquelles je n'ai pas forcément la main

                  Si ce n'est pas des fenêtres transitoires ou qui ne sont pas manageables par le code appelant, vous avez clairement de très gros problèmes d'architecture dans votre application.

                  >(ou partagées avec d'autres projets qui fonctionnent différemment).

                  Justement, le code appelant doit pouvoir être libre de faire comme il veut, donc avec son Design Pattern de création d'IHM qui lui est propre.

                  En résumé, j'ai l'impression que vous avez pas mal de problème parce qu'il y a des défauts d'architecture à la base => donc pas forcement de solution simple "clé en main" pour récupérer ces grosses bourdes.

                  Donc, si vous êtes en mode "taupe/couteau entre les dents" pour ne pas ré-architecturer votre application, il vous reste les méthodes "Golgoth" :

                  https://stackoverflow.com/questions/1603600/winforms-is-there-a-way-to-be-informed-whenever-a-form-gets-opened-in-my-applic

                  surtout la réponse de Hasani Blackwell qui utilise des primitives de "hooking" qui fonctionnent particulièrement bien avec WinForm, car ce framework utilise directement les fenêtres GDI de Windows (heu, là, on oublie la portabilité de .NET).

                  Vous verrez dans les autres réponses, que l'approche "manager" avec un Design Pattern de création (via héritage (très naïf), ou via centralisation des création par exemple ) est une approche "classique".

                  Il y a bien d'autres moyens encore plus détourné s(hacking de framework .NET etc...) mais c'est largement plus complexe que le hooking de Hasani Blackwell. Donc, si vous êtes capable de facilement convertir la solution de Hasani Blackwell en un manager de fenêtres "aliens" qui crée une fenêtre "terrestre" fantôme quand le compteur de fenêtre WinForm passe de 0 à 1 et la détruit quand le compteur passe de 1 à 0, ça serait déjà pas mal.

                  En fait, je suis pas sûr que cela soit plus fiable qu'avec votre pooling sur votre "Application.OpenForms", mais je suis assez sceptique sur le fait que cette primitive fonction "correctement" dans une application WPF.

                  Sans une architecture prévus pour, je ne pense que vous obtiendrez quelque-chose de totalement fiable.

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                    6 janvier 2022 à 21:30:15

                    Je vous remercie très sincèrement sur le temps que vous avez pris pour partager toutes ces informations 🙂.
                    Sur le fond, je suis assez d'accord avec vos réflexions sur l'architecture. 
                    Juste une remarque :
                    >Justement, le code appelant doit pouvoir être libre de faire comme il veut, donc avec son Design Pattern de création d'IHM qui lui est propre
                    Certaines api fournies par les éditeurs, ne permettent pas (ou n'encourage pas / ne documentent pas) de créer les fenêtres, mais permettent leur affichage via une fonction "displaySomething" par exemple.
                    Après on peut débattre de l'intérêt de garder l'appli ouverte si il ne reste plus que ce type de fenêtre, je suis d'accord 😉, mais encore une fois, ce n'est pas la question.
                    La méthode de Hasani Blackwell correspond exactement à ce que je cherchais, merci 🙂, je vais clôturer.
                    Juste pour information, concernant la fonction "application.OpenForms", elle semble bien fonctionner sur wpf:
                    https://stackoverflow.com/questions/42411606/get-list-of-open-wpf-windows-in-forms-application
                    • Partager sur Facebook
                    • Partager sur Twitter
                      7 janvier 2022 à 13:05:38

                      Merci pour ces retours.

                      >mais permettent leur affichage via une fonction "displaySomething" par exemple.

                      Je ne suis pas sur de tout comprendre.

                      Les architectures qui permettent l'affichage "composite" via plug-ins ou autre sont assez spécifiques.

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                        7 janvier 2022 à 15:16:17

                        Oui, en effet, je parlais bien de l'utilisation de Plug-ins.
                        • Partager sur Facebook
                        • Partager sur Twitter
                          7 janvier 2022 à 18:37:46

                          J'ai vu pas mal de solution foireuse comme sous Blender, etc...

                          C'est vraiment très très compliqué cette intégration d'IHM composite.

                          Un framework qui fonctionnait, c'était ActiveX (pour avoir un logiciel Office dans un autre logiciel office).

                          Depuis, M$ a sorti par mal de bidules qui semblent ne pas avoir pris (PRISM, MSF, etc...).

                          Mais putain, quelle usine à gaz, même avec tout l'outillage que donnait M$ pour faire ces machins ActiveX Componants.

                          Si l'instanciateur d'un hôte fourni un moyen de faire déjà un simple retour sous forme de message en bar de status ou via un messageBox model, et que c'est simple à utiliser, bin c'est très bien.

                          Fiare une usine à gaz de "pré-porcessing" des messages avant l'hôte, "post-processing" après l'hôte, mise en place de subclassing/hooking pour s'intégrer dans le processing graphique de l'hôte, etc....

                          Tout ça pour afficher une fenêtre dégueulasse avec des ressources de fenêtre (icônes, etc...) datant de Borland Paradox (~1985) et qui n'est même pas associé au "theme dark/white/..." de l'application hôte, bofbof.

                          Que l'application hôte soit la seule à afficher quelque chose, c'est vraiment plus simple.

                          Vous avez des exemples d'applications à affichage composite qui tiennent la route ?

                          • Partager sur Facebook
                          • Partager sur Twitter
                          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                            7 janvier 2022 à 19:55:59

                            >Vous avez des exemples d'applications à affichage composite qui tiennent la route ?
                            Pas d'application grand public, mais en entreprise il me semble (semblait peut être alors) assez courant de s'interfacer avec des applications métiers (d'éditeur tiers) existantes, l'intérêt étant souvent d'étendre les fonctionnalités de l'application métier.
                            >Tout ça pour afficher une fenêtre dégueulasse avec des ressources de fenêtre (icônes, etc...) datant de Borland Paradox (~1985) et qui n'est même pas associé au "theme dark/white/..." de l'application hôte, bofbof
                            À double tranchant, c'est vrai que le résultat n'est pas toujours homogène, mais le principal avantage est que les utilisateurs (re) connaissent leur application métier.
                            • Partager sur Facebook
                            • Partager sur Twitter
                              8 janvier 2022 à 19:45:39

                              Dans le cadre pro, c'est plutôt des développement spécifique à un logiciel précis et il n'y a pas de recherche de portabilité.
                              • Partager sur Facebook
                              • Partager sur Twitter
                              Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.

                              Shutdown mode for WPF and forms

                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                              • Editeur
                              • Markdown