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 :

Code behind et Vue du Modèle


Sujet :

Windows Presentation Foundation

  1. #1
    Membre habitué Avatar de titourock
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2008
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2008
    Messages : 156
    Points : 190
    Points
    190
    Par défaut Code behind et Vue du Modèle
    Bonjour à tous,

    J'examine depuis quelques semaines maintenant le (fort séduisant) pattern MVVM et je me pose une question (voir plus même ) :

    Un des conséquences (objectifs?) est de n'avoir que très peu, voir aucun code, dans le code behind des vues.
    Ma question est alors simple : auriez-vous un exemple de code (i.e de cas concret(s)) devant absolument se trouver dans le code behind et n'ayant "rien à faire" dans la vue du modèle ?

    Cette question me taraude depuis quelques temps déjà...

    Merci d'avance
    Dans la vie, il y a trois sortes de mathématiciens : ceux qui savent compter et ceux qui ne savent pas...

    Ne jamais jouer à saute-moutons avec une licorne...

  2. #2
    Membre expert
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    2 210
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 210
    Points : 3 015
    Points
    3 015
    Par défaut
    Salut,

    Un des conséquences (objectifs?) est de n'avoir que très peu, voir aucun code, dans le code behind des vues.
    Conséquence oui pas objectif (à mon sens en tout cas).

    Un exemple, pour un Drag & Drop, on ne mettra pas le code de l'évènement DragOver dans le ViewModel car c'est trop lié à la vue :
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        private void ctrl_DragOver(object sender, DragEventArgs e) {
          if (e.Data.GetDataPresent(typeof(MonObjet)))
            e.Effects = System.Windows.DragDropEffects.Copy;
          else
            e.Effects = System.Windows.DragDropEffects.None;
        }

  3. #3
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par titourock Voir le message
    la vue du modèle
    En général le ViewModel est plutôt considéré comme un "modèle de la vue" que comme une "vue du modèle"

    Citation Envoyé par titourock Voir le message
    Un des conséquences (objectifs?) est de n'avoir que très peu, voir aucun code, dans le code behind des vues.
    C'est une conséquence, mais certainement pas un objectif... une idée reçue très répandue est qu'il est "interdit" d'écrire du code-behind en MVVM, mais c'est une erreur. Même Josh Smith, "gourou" de MVVM, met du code-behind dans ses vues... (regarde par exemple l'application BubbleBurst qui sert d'illustration au livre Advanced MVVM)

    Citation Envoyé par titourock Voir le message
    Ma question est alors simple : auriez-vous un exemple de code (i.e de cas concret(s)) devant absolument se trouver dans le code behind et n'ayant "rien à faire" dans la vue du modèle ?
    J'ai pas d'exemple concret en tête, mais ça arrive de devoir le faire. Dans certains cas, le code-behind est la meilleure solution pour arriver à ce que tu veux (typiquement, pour des choses entièrement liées à l'interface graphique, sans rapport avec le ViewModel)
    Cela dit, s'il y a des choses que tu fais fréquemment dans le ViewModel, ça peut être intéressant d'extraire ce comportement pour en faire un propriété attachée réutilisable

  4. #4
    Membre habitué Avatar de titourock
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2008
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2008
    Messages : 156
    Points : 190
    Points
    190
    Par défaut
    Citation Envoyé par tomlev Voir le message
    En général le ViewModel est plutôt considéré comme un "modèle de la vue" que comme une "vue du modèle"
    Très bonne remarque, très lourde erreur de ma part merci de me l'avoir signalée.

    Citation Envoyé par tomlev Voir le message
    C'est une conséquence, mais certainement pas un objectif
    Je pense tout de même que c'est un "mini objectif" dans le sens où l'on cherche, il me semble, à séparer le coté affichage pur de la gestion des actions utilisateurs. J'y vois alors un objectif dans le sens où le code behind doit être réduit au minimum, respectant ainsi la "philosophie xaml" qui fait que ce sont les composants graphiques (type listbox, combox etc...) qui se chargent à partir d'une liste d'afficher un menu déroulant et pas comme dans une jsp où l'on doit faire une boucle sur la collection sous-jacente (mais j'utilise peut-être mal les jsp )

    Autrement dit, "rendre à la vue ce qui appartient à la vue" (ce qui me fait dire qu'en fait "objectif" est ici pour moi synonyme de "ligne de conduite")

    Quant à Josh Smith cela fait longtemps qu'il est mon gourou, je viens juste d'acheter son livre et je voulais avoir parallèlement d'autres avis


    Citation Envoyé par tomlev Voir le message
    Cela dit, s'il y a des choses que tu fais fréquemment dans le ViewModel, ça peut être intéressant d'extraire ce comportement pour en faire un propriété attachée réutilisable
    Peux-tu préciser ce dernier point ? cela m'intéresserait beaucoup.
    Dans la vie, il y a trois sortes de mathématiciens : ceux qui savent compter et ceux qui ne savent pas...

    Ne jamais jouer à saute-moutons avec une licorne...

  5. #5
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par titourock Voir le message
    Je pense tout de même que c'est un "mini objectif" dans le sens où l'on cherche, il me semble, à séparer le coté affichage pur de la gestion des actions utilisateurs.
    Non, on cherche à séparer la vue (affichage + actions utilisateurs) de la logique métier. L'affichage se fait en fonction des données du ViewModel, et les actions utilisateurs déclenchent des commandes du ViewModel. Donc tu peux très bien avoir du code-behind tout en maintenant la séparation entre vue et le reste... si tu ne mets dans le code-behind que du code strictement lié à la vue, je ne vois pas où est le problème. Par contre, il ne faut évidemment pas y mettre des choses qui relèvent de la logique métier de l'application. Le ViewModel doit rester indépendant de la vue, donc ne pas dépendre de quelque chose qui est implémenté dans le code-behind de la vue.

    Si je dis tout ça, ce n'est pas du tout parce que je suis adepte du code-behind (en fait j'évite presque toujours d'en mettre), c'est simplement pour souligner que ce n'est pas du tout un aspect fondamental de MVVM.

    Citation Envoyé par titourock Voir le message
    Peux-tu préciser ce dernier point ? cela m'intéresserait beaucoup.
    Exemple typique : tri d'une GridView
    C'est quelque chose que tu peux implémenter dans le code-behind (ça ne concerne que la présentation et n'a pas d'impact sur la logique métier), mais si tu le fais souvent, il vaut mieux le refactoriser... et si en plus, tu peux déclarer ce comportement directement en XAML, c'est encore mieux

  6. #6
    Membre habitué Avatar de titourock
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2008
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2008
    Messages : 156
    Points : 190
    Points
    190
    Par défaut
    Décidément mon vocabulaire est à revoir...par "gestion des actions utilisateurs" j'entendais "logique métier". J'essaye donc de reformuler mieux mon propos en espérant que tu n'aies rien à y redire

    Pour moi, la très belle et très élégante puissance de WPF avec le MVVM est que l'affichage tend à être purement descriptif (c'est à dire avec peu de code behind) i.e "la collection à afficher de ma combobox s'appelle MaCollection et après Monsieur binding débrouille toi pour me trouver la collection qui a ce nom, la combobox fera le travail d'affichage" et pareil pour les commandes...

    Ce qui pour moi contraste avec les jsp où si l'on appliquait la logique de cette dernière, on serait obligé de faire une "boucle dans le XAML" pour afficher la collection...

    Dans la série question existencielle...je m'intéresse également à un des articles de Thomas Lebrun permettant d'utiliser les commandes sur un évènement "quelconque" (et donc pas le bon vieux Command="{Binding MaBonneVieilleCommande}")

    Là aussi je pense qu'il faut en user avec parcimonie (d'où la difficulté...) et j'ai un exemple concret : dans mon projet, j'ai une grille (composant acheté) bindée sur une source dont je peux sélectionner plusieurs cellules (et donc pas selection de toute la ligne comme j'ai pu le voir dans un très bon tutoriel sur developpez avec ICollectionView)
    La question que je me pose depuis pas mal de temps est de savoir où mettre l'évènement "ma selection change" sachant que la multisélection n'est pas géré par CollectionView il me semble...

    Que me conseillerais-tu? Merci d'avance pour le temps consacré et pardon si mes questions sont trop triviales
    Dans la vie, il y a trois sortes de mathématiciens : ceux qui savent compter et ceux qui ne savent pas...

    Ne jamais jouer à saute-moutons avec une licorne...

  7. #7
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par titourock Voir le message
    Dans la série question existencielle...je m'intéresse également à un des articles de Thomas Lebrun permettant d'utiliser les commandes sur un évènement "quelconque" (et donc pas le bon vieux Command="{Binding MaBonneVieilleCommande}")
    Cette solution est intéressante, mais elle ne fonctionne que pour un seul évènement... si tu as plusieurs évènements à mapper sur des commandes, c'est mort. Je te conseille plutôt les attached behaviors de Marlon Grech, qui permettent de gérer plusieurs évènements (d'ailleurs il y a le lien dans l'article de Thomas)

    Citation Envoyé par titourock Voir le message
    Là aussi je pense qu'il faut en user avec parcimonie (d'où la difficulté...) et j'ai un exemple concret : dans mon projet, j'ai une grille (composant acheté) bindée sur une source dont je peux sélectionner plusieurs cellules (et donc pas selection de toute la ligne comme j'ai pu le voir dans un très bon tutoriel sur developpez avec ICollectionView)
    La question que je me pose depuis pas mal de temps est de savoir où mettre l'évènement "ma selection change" sachant que la multisélection n'est pas géré par CollectionView il me semble...
    Ben ça dépend... l'évènement "SelectionChanged" (ou quel que soit son nom) a sûrement des paramètres qui sont spécifiques à ce contrôle. Donc si tu gères cet évènement dans le ViewModel, tu introduis une dépendance à ce contrôle particulier... or le ViewModel ne devrait jamais dépendre de la vue.

    Ce que tu pourrais éventuellement faire, c'est créer un behavior (via une propriété attachée) pour ce contrôle, qui intercepte l'évènement, en extrait les informations utiles au ViewModel, et les transmet à la commande associée.

    Le principe pour créer des behaviors pour un contrôle est toujours le même. Pour l'exemple, on va supposer que le contrôle s'appelle Toto, et que tu veux gérer un évènement Titi (de type EventHandler, pour faire simple...). Il faut que tu crées une classe statique TotoBehaviors, avec une propriété attachée Titi de type ICommand :

    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    public static class TotoBehaviors
    {
        // Déclaration de la propriété attachée
        public static readonly DependencyProperty TitiProperty =
            DependencyProperty.RegisterAttached(
                "Titi",                     // Nom de la propriété
                typeof(ICommand),           // Type de la propriété
                typeof(TotoBehaviors),      // Type qui déclare la propriété
                new UIPropertyMetadata(
                    null,                   // Valeur par défaut de la propriété
                    TitiChanged));          // Callback appelé quand la valeur change
     
        // Callback appelé quand la valeur de la propriété change
        // C'est là qu'on s'abonne à l'évènement
        private static void TitiChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            Toto toto = (Toto)o;
     
            // S'il y avait une commande associée avant, on se désabonne de l'évènement
            if (e.OldValue != null)
                toto.Titi -= toto_Titi;
     
            // S'il y a maintenant une commande associée, on s'abonne à l'évènement
            if (e.NewValue != null)
                toto.Titi += toto_Titi;
        }
     
        // Gestionnaire de l'évènement Titi
        private static void toto_Titi(object sender, EventArgs e)
        {
            Toto toto = (Toto)sender;
            ICommand command = toto.GetValue(TitiProperty);
     
            // On déclenche la commande associée à l'évènement
            // On peut éventuellement passer quelque chose à la place de null si ça a un sens...
            if (command != null && command.CanExecute(null))
            {
                command.Execute(null);
            }
        }
    }

    En XAML, tu l'utilises comme ça :


    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    <Toto b:TotoBehaviors.Titi="{Binding TitiCommand}" />

    (b étant un xmlns mappé sur le namespace où TotoBehaviors est déclaré)

  8. #8
    Membre habitué Avatar de titourock
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2008
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2008
    Messages : 156
    Points : 190
    Points
    190
    Par défaut
    Oui, je parle des attached behavior de l'article de Thomas Lebrun que tu as cité. Je vais me pencher sérieusement sur cet exemple.
    Merci encore, je referme donc ce topic
    Dans la vie, il y a trois sortes de mathématiciens : ceux qui savent compter et ceux qui ne savent pas...

    Ne jamais jouer à saute-moutons avec une licorne...

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 02/05/2010, 22h30
  2. [C#] creer et afficher une table en code behind
    Par shams dans le forum ASP.NET
    Réponses: 9
    Dernier message: 13/07/2005, 16h51
  3. [C#]ajout code dans code behind
    Par liliprog dans le forum ASP.NET
    Réponses: 8
    Dernier message: 21/06/2005, 11h03
  4. Réponses: 5
    Dernier message: 24/05/2005, 12h31
  5. [VB.NET] Création d'un tableau en code behind
    Par netr dans le forum ASP.NET
    Réponses: 6
    Dernier message: 11/05/2004, 10h02

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