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 :

Comprendre quelque principe de base du MVVM


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    929
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 929
    Points : 312
    Points
    312
    Par défaut Comprendre quelque principe de base du MVVM
    Bonjour,

    Je viens de me mettre à WPF et XAML, et j'ai découvert le modèle MVVM.
    J'en suis bien-sur au base et commence à suivre une formation.

    Je verrais peut être voir la solution lorsque je vais avancer, mais un truc me chagrine.

    Sur les essaies basique du MVVM que j'ai effectué, on a une vue, un modèle et une vuemodèle.

    Cela fonctionne, mais dans mon cas d'application(pour mon logiciel), j'ai une vue qui doit recevoir des paramètres qui sont en permanence mis à jour.

    Actuellement en WinForm on a un timer qui lit les variables afin de mettre à jour la vue. Je voie pas trop comment mettre à jour les variables, faut t'il toujours un timer dans la vuemodèle?

    Actuellement dans la partie modèle j'ai fait l'essaie de mettre à jour la variable par un timer qui l’incrémente toute les secondes. Mais cette variable n'est pas mise a jour dans la vue.


    C'est surement une question bête, mais s'il faut remettre un timer dans le vuemodèle, je vois pas trop l’intérêt.


    Merci

  2. #2
    Membre éprouvé Avatar de WDKyle
    Homme Profil pro
    Analyste-Programmeur
    Inscrit en
    Septembre 2008
    Messages
    1 200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-Programmeur

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 200
    Points : 962
    Points
    962
    Par défaut
    Bonsoir,

    Tu as bien implémenter l'interface INotifyPropertyChanged ?

  3. #3
    Membre averti Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    929
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 929
    Points : 312
    Points
    312
    Par défaut
    Bonsoir,

    J'ai suivi les consignes, mais je pense que quelque chose se passe mal ou j'ai mal fait les choses effectivement.

    Ci dessous les codes employés:

    Vue:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    <Grid>
            <StackPanel>
                <TextBox Text="{Binding MaValeur}" />
                <CheckBox IsChecked="{Binding ModificationModèle}" />
            </StackPanel>
    </Grid>
    VueModèle:
    Code : 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
    43
    44
    45
    46
    47
    48
     
     class Vue_Modèle : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            protected virtual void OnPropertyChanged(string propertyName)
            {
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
     
            Modèle monModèle;
     
            public Vue_Modèle()
            {
                monModèle = new Modèle();
                MaValeur = monModèle.Valeur;
                ModificationModèle = false; 
            }
     
            private int maValeur;
            public int MaValeur
            {
                get { return this.maValeur;  }
                set
                {
                    this.maValeur = value;
                    OnPropertyChanged("MaValeur");
     
                    if (ModificationModèle == true)
                    {
                        monModèle.Valeur = MaValeur;
                    }
                }
            }
     
            private bool modificationModèle;
            public bool ModificationModèle
            {
                get { return this.modificationModèle; }
                set
                {
                    this.modificationModèle = value;
                    OnPropertyChanged("ModificationModèle");
                }
            }
        }
    Modèle:
    Code : 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
     
    class Modèle
        {
            public int Valeur { get; set; }
            public DispatcherTimer Timer1;
     
            public Modèle()
            {
                this.Valeur = 0;
                this.Timer1 = new DispatcherTimer();
                this.Timer1.Tick += new EventHandler(Timer1_Tick);
                this.Timer1.Interval = new TimeSpan(0, 0, 1);
                this.Timer1.Start();
            }
     
            private void Timer1_Tick(object sender, EventArgs e)
            {
                this.Valeur = this.Valeur + 1;
                if (this.Valeur >= 100)
                {
                    Timer1.Stop();
                }
            }
        }
    La seul chose que j'ai effectué c'est de rajouter un timer qui incrémente la variable "Valeur" jusqu'à 100.
    Au débogage cela fonctionne bien le timer et la variable, mais sur la vue je n'est que 0.
    Je voie pas trop a quoi sert le checkbox, mais quand je l'active j'ai bien "public bool ModificationModèle" qui est lancé.

    Je me précipite un peu trop je pense, mais je comprend pas trop cette exemple si l'on ne peut pas mettre à jour le champs de la vue. Ou si faut l'appeler tout le temps.


    Merci

    [Edit1]

    Je pense avoir compris, c'est pas dans le modèle que je dois effectué la mise à jour des données, mais dans la vueModèle, si j'ai bien compris, en tout cas j'ai fait l'essaie et cela fonctionne. Au final, si encore une fois j'ai bien compris, dans modèle il doit y avoir uniquement les variables à mettre à jour et c'est la classe vueModèle qui doit en faire la demande. ou qui en fait l’intermédiaire.

  4. #4
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 442
    Points
    4 442
    Par défaut
    bonjour

    Les interactions avec le Model se font par le biais de la View laquelle notifie le ViewModel lequel met à jour le Model...

    Suivant ce schéma ,ton timer devrait se trouver dans la View et incrementer le ViewModel ....

    code .cs du model :
    Code : 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
     
    namespace WpfModel.Model
    {
        public class MyModel
        {
            private int _valeur;
            public int Valeur
            {
                get { return _valeur; }
                set
                {
                    _valeur = value;
     
                }
     
            }
        }
    }
    code du VM:

    Code : 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
    43
     
    using WpfModel.Model;//dossier model
     
    WpfModel.ViewModel
    {
        public class MyViewModel : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            protected virtual void OnPropertyChanged(string propertyName)
            {
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
            private MyModel theModel;
            public MyModel TheModel
            {
                get { return this.theModel; }
                set
                {
                    this.theModel = value;
                    OnPropertyChanged("TheModel");
     
     
                }
            }
            public int Valeur
            {
                get { return TheModel.Valeur; }
                set
                {
                    this.TheModel.Valeur = value;
                    OnPropertyChanged("Valeur");
     
                }
            }
            public MyViewModel()
            {
                TheModel = new MyModel();
            }
        }
    }
    code xaml View :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    <Window x:Class="WpfModel.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Window1" Height="300" Width="300">
        <Grid>
            <Grid>
                <StackPanel>
                    <TextBox Text="{Binding Valeur}" />
                </StackPanel>
            </Grid>
        </Grid>
    </Window>
    son code .cs

    Code : 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
     
    using WpfModel.ViewModel; //dossier ViewModel
    using System.Windows.Threading;
     
    namespace WpfModel
    {
        /// <summary>
        /// Logique d'interaction pour Window1.xaml
        /// </summary>
        public partial class Window1 : Window
        {
            private MyViewModel vm;
            public DispatcherTimer Timer1;
            public Window1()
            {
                InitializeComponent();
                vm = new MyViewModel();
                this.DataContext = vm;
                this.Timer1 = new DispatcherTimer();
                this.Timer1.Tick += new EventHandler(Timer1_Tick);
                this.Timer1.Interval = new TimeSpan(0, 0, 1);
                this.Timer1.Start();
            }
            private void Timer1_Tick(object sender, EventArgs e)
            {
                this.vm.Valeur += 1;
                if (this.vm.Valeur >= 100)
                {
                    Timer1.Stop();
                }
            }
     
        }
    }
    bon code...

  5. #5
    Membre averti Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    929
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 929
    Points : 312
    Points
    312
    Par défaut
    Bonjour MABROUKI et les autres bien sûr,

    C'est la tout mon problème, je ne conçois pas que se soit la vue qui mette à jour le reste, bien sûr il y a les événements sur les boutons ou un textbox sa c'est une évidence.

    Mais je vais être obligé de vous expliquer un peu plus en détails le but de mon application.
    ------------------------------------------------------------------------------------------------------
    L'application sert a visualiser et modifier des paramètres d'un ordinateur embarqué que l'on appelle supervision.
    La supervision se trouve dans une armoire et elle gère la charge de batteries en fonction du secteur, panneau solaire ou éolien... de plus elle supervise aussi la tension d'utilisation client ainsi que les alarmes éventuelles.

    Mon logiciel communique avec cette supervision afin d'afficher les valeurs que le client veux visualiser (il y a plusieurs formulaires), mais suivant le niveau d’accès peu aussi paramétrer la supervision (sa configuration), changer une tension, un seuil d'alarme etc...

    Lorsque mon logiciel se lance ont le connecte (en port COM ou Ethernet) à la supervision, et suivant la vue que le client visualise un poller interroge la supervision afin de mettre a jour ces variables, la vue les visualises ensuite.

    Nom : FonctionAppli.png
Affichages : 339
Taille : 24,9 Ko

    ------------------------------------------------------------------------------------------------------

    Créer toute la gestion du dialogue avec la supervision dans la vue me semble contraire au but de la VMMV, mais bon comme je l'ai dit je début dans cette technologie, mais pour moi mon but est d'avoir une application qui puisse tourner (presque) sans la vue.
    peut être que le VMMV n'est pas adapté à ce que je recherche.

    Hier je n'ai pas eue le temps de continuer la formation, je le fait sur mon temps perso, j’espère que ce soir j'avancerais un peu.

  6. #6
    Membre éprouvé Avatar de WDKyle
    Homme Profil pro
    Analyste-Programmeur
    Inscrit en
    Septembre 2008
    Messages
    1 200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-Programmeur

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 200
    Points : 962
    Points
    962
    Par défaut
    Bonjour,

    Pour moi, il ne devrait pas avoir d’"intelligence" coté Vue...

    Je placerais cela dans le ViewModel ou à la rigueur dans le Model, bien que ce dernier ne me sert que de "squelette" pour la structure de données.

  7. #7
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 905
    Points : 1 923
    Points
    1 923
    Par défaut
    Citation Envoyé par MABROUKI Voir le message
    Suivant ce schéma ,ton timer devrait se trouver dans la View et incrementer le ViewModel ....
    Je suis d'accord avec WDKyle sur ce point. Si Timer il y a dans la vue il ne peut servir qu'à gérer de l'affichage (champ clignotant, rafraîchissement...). Interroger périodiquement un service distant c'est le rôle du Model ou d'un contrôleur.

    Quand au ViewModel je le considère comme une représentation abstraite, fonctionnelle du contexte, c.à.d des données présentées et des actions possibles ; il répond à la question "que dois me permettre de connaître ou de faire l'application" (objets de données et commandes), pas "comment doit-elle le faire" (affichage ou logique métier). D'ailleurs un ViewModel correct devrait pouvoir être interrogé par une application console ou un test unitaire.

    Par exemple valider une tâche :
    - dans la vue un bouton à cliquer (sur un écran tactile ça pourrait être un glisser vers la gauche) ;
    - dans le modèle de vue une ICommand ;
    - dans le modèle la méthode permettant de valider effectivement la tâche (avec éventuellement un appel vers un serveur d'application ou une base de données).

    @megamario :
    WinForms n'est pas totalement incompatible avec MVVM, simplement certaines choses qui sont gérées automatiquement dans WPF (ex. les bindings) devront être gérées à la main en WinForms. Rien ne t'empêche par exemple d'avoir un VM qui implémente INotifyPropertyChanged et d'y abonner une Form pour effectuer les mises-à-jour de l'écran lorsque les propriétés changent ; le clic qu'un bouton peut appeler la méthode Execute de l'objet ICommand fourni par le VM via une propriété... Si tu dois / peux un jour passer sur WPF la transition sera plus rapide.

    En terme d'architecture tu peux aussi envisager d'avoir certains traitements côté serveur plutôt que sur une application locale afin de mettre des contrôles de sécurité qui ne pourront pas être contournés simplement en modifiant des paramètres de l'application (l'application Snoop par exemple permet d'explorer sans retenue l'arbre visuel d'une application WPF et de modifier des propriétés ; tu peux même la tester sur Visual Studio).

  8. #8
    Membre averti Avatar de megamario
    Homme Profil pro
    VB6/VB.net/C/C++/C#
    Inscrit en
    Septembre 2008
    Messages
    929
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : VB6/VB.net/C/C++/C#
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2008
    Messages : 929
    Points : 312
    Points
    312
    Par défaut
    Citation Envoyé par Noxen Voir le message
    D'ailleurs un ViewModel correct devrait pouvoir être interrogé par une application console ou un test unitaire.
    C'est exactement à cela que je pensais.

    Citation Envoyé par Noxen Voir le message
    J
    Par exemple valider une tâche :
    - dans la vue un bouton à cliquer (sur un écran tactile ça pourrait être un glisser vers la gauche) ;
    - dans le modèle de vue une ICommand ;
    - dans le modèle la méthode permettant de valider effectivement la tâche (avec éventuellement un appel vers un serveur d'application ou une base de données).
    Je le pensais comme cela aussi, cela me rassure.


    Citation Envoyé par Noxen Voir le message

    @megamario :
    WinForms n'est pas totalement incompatible avec MVVM, simplement certaines choses qui sont gérées automatiquement dans WPF (ex. les bindings) devront être gérées à la main en WinForms. Rien ne t'empêche par exemple d'avoir un VM qui implémente INotifyPropertyChanged et d'y abonner une Form pour effectuer les mises-à-jour de l'écran lorsque les propriétés changent ; le clic qu'un bouton peut appeler la méthode Execute de l'objet ICommand fourni par le VM via une propriété... Si tu dois / peux un jour passer sur WPF la transition sera plus rapide.
    C'est effectivement ce que j'ai essayé de faire, je ne vous l'ai pas dit, mais le projet de base était en VB6, avec des modifications des objet graphique dans tout les sens, depuis toutes les classes, chaque classe accédant à tout, s'appelant l'une vers l'autre, bref un peu le bazar, j'ai bien galérer à reprendre ce code, c'est clair qu'il aurait fallu reprendre le tout de zero, mais j'était seul sur cette conversion vers VB.net et en plus à mes heure perdu.
    Mais j'ai vraiment essayé de changer tout cela en pensant objet (pas trop le choix en .net de toute manière), à la différence que j'ai créé des classes de gestion de chaque vue et c'est elle qui instancie la vue géré (ainsi elle peut y accéder plus facilement), pas besoin d'utiliser des delegate .

    Par contre j'ai essayé de faire des controlUser (dll) en WPF et les utiliser dans un WinForm, mais il en veux pas dommage, mes dessins sont pas mal, mais heureusement cela ce met à jour toutes les 3 à 5 secondes sinon le scintillement agace. Et encore je rafraîchi maintenant uniquement si la valeur à changer.


    Citation Envoyé par Noxen Voir le message

    En terme d'architecture tu peux aussi envisager d'avoir certains traitements côté serveur plutôt que sur une application locale afin de mettre des contrôles de sécurité qui ne pourront pas être contournés simplement en modifiant des paramètres de l'application (l'application Snoop par exemple permet d'explorer sans retenue l'arbre visuel d'une application WPF et de modifier des propriétés ; tu peux même la tester sur Visual Studio).
    La j'avoue que je comprend pas trop, mais mon appli au final à besoin d'être 100% autonome, certains site étant complètement coupé du monde, sans liaison Ethernet ni même GSM parfois. A part des liaisons satellitaire ou l'on a un site équipé comme cela en France (en haute montagne), mais les liaisons sont catastrophique, très longue et instable, c'est pas de la 4G .

Discussions similaires

  1. [AJAX] [Xajax] xajax principe de base
    Par Didibzh dans le forum Général JavaScript
    Réponses: 14
    Dernier message: 18/06/2007, 12h00
  2. Principes de base GUI
    Par sone47 dans le forum Interfaces Graphiques
    Réponses: 2
    Dernier message: 14/02/2007, 16h46
  3. Réponses: 12
    Dernier message: 06/10/2006, 13h35
  4. Quelques questions de base
    Par Chess0 dans le forum DirectX
    Réponses: 2
    Dernier message: 19/12/2005, 04h35
  5. [principe de base] Objets composés d'objets
    Par brousaille dans le forum JDBC
    Réponses: 11
    Dernier message: 09/02/2005, 19h13

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