IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Presentation Foundation Discussion :

[MVVM] Comment fermer une Window à partir d'un ViewModel


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Octobre 2007
    Messages
    66
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 66
    Par défaut [MVVM] Comment fermer une Window à partir d'un ViewModel
    Bonjour,

    j'ai surfé sur le net pour trouvé une solution à mon problème :
    Mon application principale lance une fenetre secondaire avec une textBox et 2 boutons (OK et Cancel). Jusque là rien d'original.
    Je voudrais lors que l'on appuie sur un bouton effectuer une commande puis fermer la fenêtre.

    Facile!!! Sauf si on veut respecter le pattern MVVM

    En effet, dans mon ViewModel, je n'ai aucune information sur la View (à priori).

    Le lien suivant http://stackoverflow.com/questions/5...329467#3329467

    propose plusieurs solutions mais d'après vous laquelle est la meilleur?

    Merci

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par L'elfe d'Azur Voir le message
    Facile!!! Sauf si on veut respecter le pattern MVVM

    En effet, dans mon ViewModel, je n'ai aucune information sur la View (à priori).
    Effectivement... mais dans ce cas, comment as-tu ouvert la 2e fenêtre ?

    Il y a différentes approches pour afficher des dialogues en MVVM. Personnellement, j'utilise une approche à base de services :
    - une interface IDialogViewModel, implémentée par les ViewModels correspondant à un dialogue
    - une interface IDialogService qui permet d'afficher une instance de IDialogViewModel
    - un ServiceLocator qui permet à mes ViewModels de récupérer une instance de IDialogService

    Mon interface IDialogViewModel a un évènement CloseRequested, déclenché quand le ViewModel veut se fermer. L'implémentation de IDialogService s'abonne à cet évènement et ferme la fenêtre quand il se produit

    Sinon la solution dans le lien que tu as posté est pas mal : le fait d'affecter une valeur à DialogResult ferme la fenêtre de dialogue (mais ça ne fonctionne que si elle a été ouverte avec ShowDialog)

  3. #3
    Membre confirmé
    Inscrit en
    Octobre 2007
    Messages
    66
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 66
    Par défaut
    Effectivement... mais dans ce cas, comment as-tu ouvert la 2e fenêtre ?
    Bien évidemment à partir de mon viewModel
    Je n'avais pas l'impression de casser principe de ce pattern car je ne fais que créer et afficher la seconde fenêtre (et c'est aussi ce qu'il me semble avoir lu).

    Finalement j'ai opté pour la solution proposée par Budda :
    dans mon viewmodel, je crée un event et j'abonne au moment de la création de ma seconde fenêtre la méthode Close à cet event

    Cela marche bien et est vraiment facile à mettre en place.

    Merci pour ta réponse, je vais aussi essayer d'implémenter ta proposition pour voir ce qui me plait le plus

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par L'elfe d'Azur Voir le message
    Je n'avais pas l'impression de casser principe de ce pattern car je ne fais que créer et afficher la seconde fenêtre (et c'est aussi ce qu'il me semble avoir lu).
    Ben si on veut respecter strictement le pattern, il ne faut jamais faire référence à un composant graphique dans le ViewModel. Si tu affiches une fenêtre, tu ne peux plus faire de tests unitaires sur ton ViewModel par exemple...

  5. #5
    Membre confirmé
    Inscrit en
    Octobre 2007
    Messages
    66
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 66
    Par défaut
    Tu as raison, on perd la possibilité de faire des tests sur le viewmodel.

    Mais dans ce cas, comment faire pour qu'un viewModel face apparaitre une nouvelle fenetre (ou un view tout simpement car c'est une option du menu qui fait apparaître ma seconde fenêtre pour rentrer une configuration)

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par L'elfe d'Azur Voir le message
    Mais dans ce cas, comment faire pour qu'un viewModel face apparaitre une nouvelle fenetre
    Ben justement, c'est le service dont je parlais (IDialogService) qui le fait. Tu peux avoir différentes implémentations du service :
    - une "normale" pour l'exécution, qui crée et affiche une fenêtre (le service ne faisant pas partie de la couche ViewModel, ce n'est pas un problème)
    - une "bidon" pour les tests unitaires

    Le ViewModel n'a pas besoin de savoir quelle est l'implémentation réelle du service, il lui suffit de demander une instance de IDialogService au ServiceLocator

    Ca s'utilise comme ça :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // Au démarrage de l'application :
    ServiceLocator.Instance.Register<IDialogService>(new DialogService());
     
    // Ou alors, à l'initialisation des tests unitaires :
    ServiceLocator.Instance.Register<IDialogService>(new MockDialogService());
     
     
    // Pour afficher un dialogue à partir d'un ViewModel :
    var dialog = new TextInputDialogViewModel("Hello", "What is your name ?");
    var dialogService = ServiceLocator.Instance.GetService<IDialogService>();
    bool? result = dialogService.Show(dialog);
    if (result == true)
    {
        this.UserName = dialog.Text;
    }

    Dans mon implémentation de DialogService, je crée une instance d'une classe DialogWindow, et je lui mets le IDialogViewModel comme DataContext. Le titre, les boutons et quelques autres trucs sont définis par des bindings sur les propriétés du ViewModel. Le contenu proprement dit du dialogue est un ContentControl bindé sur le ViewModel, et le DataTemplate qui va bien est automatiquement chargé en fonction du type du ViewModel

  7. #7
    Membre éclairé
    Inscrit en
    Avril 2006
    Messages
    346
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 346
    Par défaut
    Bonjour,

    le message est un peu vieux mais j'ai une question à ce sujet.

    Citation Envoyé par tomlev Voir le message

    Personnellement, j'utilise une approche à base de services :
    - une interface IDialogViewModel, implémentée par les ViewModels correspondant à un dialogue
    - une interface IDialogService qui permet d'afficher une instance de IDialogViewModel
    - un ServiceLocator qui permet à mes ViewModels de récupérer une instance de IDialogService
    Je cherche à implémenter une telle solution mais je galère un peu.
    Comment fais-tu pour retrouver la vue à afficher depuis la méthode ShowDialog (je suppose que tu as une telle méthode) de ton DialogService
    Aurais-tu un exemple de code stp ?

    Merci d'avance,
    Zoax

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par zoaax Voir le message
    Comment fais-tu pour retrouver la vue à afficher depuis la méthode ShowDialog (je suppose que tu as une telle méthode) de ton DialogService
    Je crée un DataTemplate pour le ViewModel du dialogue à afficher. La fenêtre qui sert à afficher les dialogues contient un ContentControl, qui choisit automatiquement le DataTemplate qui va bien en fonction du type du ViewModel

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. MVVM comment fermer la vue à partir du ViewModel
    Par Golzinne dans le forum Silverlight
    Réponses: 9
    Dernier message: 27/10/2015, 22h58
  2. comment fermer une form a partir d'une autre form?
    Par mead_Developper dans le forum Windows Forms
    Réponses: 1
    Dernier message: 26/06/2009, 20h54
  3. Réponses: 6
    Dernier message: 17/02/2009, 19h32
  4. Réponses: 6
    Dernier message: 20/12/2006, 19h22
  5. Comment fermer une fenetre a partir d'une frame
    Par ideal dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 18/08/2006, 13h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo