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

C# Discussion :

Mise a jour de View MVVM


Sujet :

C#

  1. #1
    Membre confirmé
    Homme Profil pro
    Ingénieur Junior développement logiciels
    Inscrit en
    Mai 2014
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Junior développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 198
    Par défaut Mise a jour de View MVVM
    Bonjour,

    Je recherche à mieux comprendre le fonctionnement du MVVM.

    Je donne pour exemple mon cas pour apprendre à utiliser du bon fonctionnement.

    J'ai donc ma view qui est binder sur ceci : public EntityCollection<CommandeFournisseurLigne> CommandeFournisseurLignes
    qui est donc disponible depuis mon ViewModel.

    Ma question est comment signaler à ma vue que cette collection à changée ? Ou comment signaler qu'une ligne de la BDD a été modifié ?

    Lequel de mon ViewModel ou Model doit implémenter InotifyPropertyChanged ? Lequel doit RaisePropertyChanged ?


    Merci

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    C'est toujours le modèle ViewModel qui doit implémenter "INotifyPropertyChanged", pas la vue. Les objets des interfaces utilisateurs vont systématiquement s'abonner à "PropertyChanged" dès qu'elle voient qu'un objet databindé implémente "INotifyPropertyChanged".
    Ensuite, c'est l'objet qui implémente "INotifyPropertyChanged" qui est responsable des moments où il déclenche les "PropertyChanged".

    Si tu communique en plus avec une BDD, normalement la vue (View et non pas ViewModel) ne doit pas communiquer directement avec les objets de la BDD mais avec les objets du modèle ViewModel. C'est le modèle ViewModel qui communique directement avec la BDD ([EDIT] qui est le modèle)
    Dernière modification par Invité ; 27/06/2014 à 13h15.

  3. #3
    Membre confirmé
    Homme Profil pro
    Ingénieur Junior développement logiciels
    Inscrit en
    Mai 2014
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Junior développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 198
    Par défaut
    Citation Envoyé par Ph_Gr Voir le message
    Bonjour,


    Si tu communique en plus avec une BDD, normalement la vue ne doit pas communiquer directement avec les objets de la BDD mais avec les objets du modèle. C'est le modèle qui communique directement avec la BDD.
    Dans mon ViewModel j'ai ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     public EntityCollection<CommandeFournisseurLigne> CommandeFournisseurLignes
            {
                get { return ObjectEntity.CommandeFournisseurLignes as EntityCollection<CommandeFournisseurLigne>; }
            }

    Donc c'est bien un objet retourné par mon ViewModel, cela ne respect pas le MVVM ?
    Si non comment dois-je procéder ? Faut-il que je créer un Objet de type intermédiaire que je met dans une Observable collection ?



    Quelque chose du genre :
    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
     private ObservableCollection<CommandeFournisseurLigneViewModel> _test = null;
            public ObservableCollection<CommandeFournisseurLigneViewModel> test
            {
                get
                {
     
                    if (_test == null)
                    {
                        _test = new ObservableCollection<CommandeFournisseurLigneViewModel>(
                            (from CFL in DataAccess.EntitiesContext.Context.CommandeFournisseurLignes
                             where CFL.IDCommandeFournisseur == CommandeFournisseur.ID
                             select CFL).ToList().Select(CFL => new CommandeFournisseurLigneViewModel(CFL)));
                    }
     
                    return _test;
     
                }
                set { _test = value; }

    C'est bien cela ?

  4. #4
    Invité
    Invité(e)
    Par défaut
    Ah oui, j'avais confondu des termes. Dans MVVM c'est vrai qu'il y a 3 parties et j'avais confondu View et ViewModel.
    Du coup je t'ai dit une ânerie, c'est bien dans le ViewModel que tu dois mettre tes INotifyPropertyChanged, puisqu'en l'occurrence ton modèle c'est ta BDD.
    Au temps pour moi...
    Dernière modification par Invité ; 27/06/2014 à 13h16.

  5. #5
    Membre confirmé
    Homme Profil pro
    Ingénieur Junior développement logiciels
    Inscrit en
    Mai 2014
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Junior développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 198
    Par défaut
    Ok,

    Par contre si tu as un petit Sample ou Tuto avec de belles explications sur le InotifyPropertyChanged et comment s'en servir proprement je veut bien.

    Merci beaucoup.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Suite à une petite recherche sur le web, je trouve celui-ci par exemple...

    Après, une petite astuce si tu es en Framework 4.5 pour le "RaisePropertyChanged" (ou NotifyPropertyChanged dans l'exemple) : grâce au nouvel attribut CallerMemberName, tu peux faire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    private void RaisePropertyChanged([CallerMemberName] string propertyName = "")
    {
       PropertyChangedEventHandler handler = this.PropertyChanged;
       if (null != handler)
          handler(this, new PropertyChangedEventArgs(propertyName));
    }
    et tu l'utilises ainsi dans l'une de tes propriétés pour signaler le changement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    private int _monChamp;
    public int MaPropriete
    {
       get{ return _monChamp; }
       set
       {
          if (_monChamp != value)
          {
              _monChamp = value;
              RaisePropertyChanged(); //Equivalent dans ce cas à RaisePropertyChanged("MaPropriete")
          }
       }
    }
    L'avantage est que si tu fais un refactoring pour renommer la propriété, pas besoin d'aller chercher dans le code les appels à la propriété.

  7. #7
    Membre confirmé
    Homme Profil pro
    Ingénieur Junior développement logiciels
    Inscrit en
    Mai 2014
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Junior développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 198
    Par défaut
    Effectivement c'est super intéressant , sa arrange bien.

    sinon merci pour l'exemple et tout.

    Mais j'ai un petit hic...

    J'ai remarqué que le code de la personne présente avant moi ressemble à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      public CommandeFournisseur CommandeFournisseur
            {
                get { return ObjectEntity.CommandeFournisseur as CommandeFournisseur; }
            }
    Il n'y a pas de set et pas de variable sur laquelle effectuer un PropertyChanged car c'est le get qui est binder sur le xaml.

    Je n'ai donc aucune idée du comment je vais faire...

    J'ai beau faire ceci dans mon code lorsque je press le button de suppression de ligne :

    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
     private ICommand _DeleteLine = null;
            public ICommand DeleteLine
            {
                get
                {
                    if (_DeleteLine == null)
     
                        _DeleteLine = new DelegateCommand<CommandeFournisseurLigne>((CommandeFournisseurLigne Parametre) => ExecuteSupprimerLigne(Parametre));
     
                    return _DeleteLine;
                }
            }
            private void ExecuteSupprimerLigne(CommandeFournisseurLigne Parametre)
            {
                DataAccess.EntitiesContext.Context.DeleteObject(Parametre);
                RaisePropertyChanged(this.GetPropertyName(() => CommandeFournisseurLignes));
            }

    Ma liste ne se met pas à jour... Peut être que l'outil infragistic XamGrid n'aime pas trop sa...

  8. #8
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Si j'ai tout compris et qu'il n'y a pas de typos dans ton code tu devrais plutôt faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    RaisePropertyChanged(this.GetPropertyName(() => CommandeFournisseur));

  9. #9
    Membre confirmé
    Homme Profil pro
    Ingénieur Junior développement logiciels
    Inscrit en
    Mai 2014
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Junior développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 198
    Par défaut
    Ok, Je vais essayer de faire ça puis je vous dirai ce que ça change mais il me semble avoir essayé mais sans conséquence (de ce que je me rappelle).
    Après je ne me rappelle pas bien. Donc je fais son demain et je reviendrai vers vous.

    Édit :
    Alors me voici avec des nouvelles qui ne m'arrangent pas du tout... En fait pour la liste des lignes de la commande j'utilise une EntityCollection qui n'implémente pas InotifyPropertyChanged de ce que j'ai réussi à comprendre.
    Je ne sais donc pas comment renvoyer les modifs que j'ai réalisées en supprimant la ligne à ma vue.
    Étant débutant c'est vraiment pas évident de trouver une solution.


    De plus ce qui suit ne change rien à ma vue :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    RaisePropertyChanged(this.GetPropertyName(() => CommandeFournisseur));
    A part que j'ai peut-être oublié quelque chose... j'imagine que je ne dois pas écrire que sa ? doit mettre quoi en plus du RaisepropertyChanged ?

    Je me permet donc de vous passer le detail de mon code...

    Ma view :
    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
     
     
               <ig:XamGrid Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" x:Name="dataGrid"
                        ItemsSource="{Binding CommandeFournisseurLignes, UpdateSourceTrigger=PropertyChanged}"
                        AutoGenerateColumns="false">
     
     
     
                <ig:XamGrid.Columns>
                    <ig:TextColumn Key="Affaire.Numero"/>
                    <ig:TextColumn Key="Description"/>
                    <ig:TextColumn Key="PrixUnitaire"/>
                    <ig:TextColumn Key="Quantite"/>
                    <ig:TextColumn Key="Total_HT"/>
     
     
                    <ig:TemplateColumn Key="ID" HeaderText="Supprimer" HorizontalContentAlignment="Center">
                        <ig:TemplateColumn.ItemTemplate>
                            <DataTemplate>
                                <Button Height="15" Style="{StaticResource RemoveButtonStyle}"
                                        CommandParameter="{Binding}"
                                        Command="{Binding DataContext.DeleteLine, 
                                    RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ig:XamGrid}}}"/>
                            </DataTemplate>
     
     
                        </ig:TemplateColumn.ItemTemplate>
                    </ig:TemplateColumn>
     
     
     
                </ig:XamGrid.Columns>
     
                <ig:XamGrid.SelectionSettings>
                    <ig:SelectionSettings CellClickAction="SelectRow" CellSelection="Single" RowSelection="Single"></ig:SelectionSettings>
                </ig:XamGrid.SelectionSettings>
                <ig:XamGrid.RowSelectorSettings>
                    <ig:RowSelectorSettings Visibility="Hidden"/>
                </ig:XamGrid.RowSelectorSettings>
     
     
                <!--Edition de ligne via double click-->
                <ig:XamGrid.EditingSettings>
                    <ig:EditingSettings AllowEditing="Row" IsMouseActionEditingEnabled="DoubleClick" 
                            IsEnterKeyEditingEnabled="True" IsF2EditingEnabled="True" 
                            IsOnCellActiveEditingEnabled="False" />
                </ig:XamGrid.EditingSettings>
     
     
                <!--Ajout de ligne via double click-->
                <ig:XamGrid.AddNewRowSettings>
                    <ig:AddNewRowSettings   AllowAddNewRow="Top"
                                IsEnterKeyEditingEnabled="True"
                                IsF2EditingEnabled="False"
                                IsMouseActionEditingEnabled="DoubleClick"
                                IsOnCellActiveEditingEnabled="True"/>
                </ig:XamGrid.AddNewRowSettings>   
            </ig:XamGrid>


    Mon ViewModel :
    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
       public class CommandeFournisseurViewModel : BaseViewModel<CommandeFournisseur>, INotifyPropertyChanged
        {
     
            public CommandeFournisseurViewModel(CommandeFournisseur CommandeFournisseur) : base(CommandeFournisseur)
            {
                Titre = "CommandeFournisseur";
     
            }
     
            public CommandeFournisseur CommandeFournisseur
            {
                get { return ObjectEntity as CommandeFournisseur; }
            }
     
     
            public EntityCollection<CommandeFournisseurLigne> CommandeFournisseurLignes
            {
                get { return ObjectEntity.CommandeFournisseurLignes as EntityCollection<CommandeFournisseurLigne>; }
            }
     
     
            private static ObservableCollection<Devise> _ListeDevise = null;
            public ObservableCollection<Devise> ListeDevise
            {
                get
                {
     
                    if (_ListeDevise == null)
                    {
                        _ListeDevise = new ObservableCollection<Devise>(DataAccess.EntitiesContext.Context.Devises);
     
                    }
     
                    return _ListeDevise;
                }
            }
     
     
            private static ObservableCollection<Fournisseur> _ListeFournisseur = null;
            public ObservableCollection<Fournisseur> ListeFournisseur
            {
                get
                {
     
                    if (_ListeFournisseur == null)
                    {
                        _ListeFournisseur = new ObservableCollection<Fournisseur>(DataAccess.EntitiesContext.Context.Fournisseurs.OrderBy(F => F.Nom));
     
                    }
     
                    return _ListeFournisseur;
                }
            }
     
     
     
            /// <summary>
            /// Test personnel pour la suppression de row
            /// </summary>
     
     
            private ObservableCollection<CommandeFournisseurLigne> _test = null;
            public ObservableCollection<CommandeFournisseurLigne> test
            {
                get {
                    if (_test == null)
                    {
                        _test = new ObservableCollection<CommandeFournisseurLigne>(CommandeFournisseur.CommandeFournisseurLignes);
     
                    }
     
                    return _test;
                }
                set { _test = value; }
            }
     
     
            private ICommand _DeleteLine = null;
            public ICommand DeleteLine
            {
                get
                {
                    if (_DeleteLine == null)
                        _DeleteLine = new DelegateCommand<CommandeFournisseurLigne>((CommandeFournisseurLigne Parametre) => ExecuteSupprimerLigne(Parametre));
     
                    return _DeleteLine;
                }
            }
            private void ExecuteSupprimerLigne(CommandeFournisseurLigne Parametre)
            {
     
                DataAccess.EntitiesContext.Context.DeleteObject(Parametre);
                RaisePropertyChanged(this.GetPropertyName(() => CommandeFournisseur));
            }
     
     
        }
    Et donc je n'arrive pas à mettre à jour la vue lors de l'utilisation de la command : DeleteLine

    Suite à ma vérification j'ai fait ceci :


    binder mon grid sur :
    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
     
            private ObservableCollection<CommandeFournisseurLigne> _test = null;
            public ObservableCollection<CommandeFournisseurLigne> test
            {
                get {
                    if (_test == null)
                    {
                        _test = new ObservableCollection<CommandeFournisseurLigne>(CommandeFournisseur.CommandeFournisseurLignes);
     
                    }
     
                    return _test;
                }
                set { _test = value; }
            }
    et changer ma fonction de suppression pour faire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    test.Remove(Parametre);
    DataAccess.EntitiesContext.Context.DeleteObject(Parametre);

    Ce qui est étrange est que DataAccess.EntitiesContext.Context.DeleteObject(Parametre) ne met pas à jour la vue. Je suis donc d'abord obliger de faire test.Remove(Parametre);

    test étant ma liste Binder lorsque je fais ceci la ligne concernant passe sa clé étrangère vers sa commande à NULL ce qui créer un bug lors de l'enregistrement en base de données car ne tolère pas les valeurs NULL dans ce champ.
    Mais grâce à la 2ème ligne celle-ci est considérer comme supprimer et est donc supprimée de la BDD.

    Je trouve ce comportement très étrange. Quel est votre avis sur la question ?


    Ben c'est raté... mon ajout ne fonctionne plus des lors que j'ai binder sur test...

    c'est quand même pourtant simple ce que je veux faire...

    Afficher la liste des lignes de la commande via une EntityCollection et pouvoir en supprimer... Jpige pas là.

    Quand je bind sur : ObjectEntity.CommandeFournisseurLignes as EntityCollection<CommandeFournisseurLigne>
    Mon ajout/modif fonctionne
    La suppression marche mais impossible de mettre à jour la View...

    Quand je bind sur : _test = new ObservableCollection<CommandeFournisseurLigne>(CommandeFournisseur.CommandeFournisseurLignes);
    J'ai que la suppression qui fonctionne...

Discussions similaires

  1. Grid view :Ajout Suppression Mise a jour Selection
    Par Ya7yaKech dans le forum ASP.NET
    Réponses: 2
    Dernier message: 14/04/2009, 20h19
  2. [Eclipse RCP] Interactions et mise à jour des views
    Par Angelure dans le forum Eclipse Platform
    Réponses: 2
    Dernier message: 18/02/2009, 15h22
  3. Mise a jour mandrake linux 9.2
    Par Otacan dans le forum Mandriva / Mageia
    Réponses: 2
    Dernier message: 02/04/2004, 22h47
  4. [] [Install] Problème de mise à jour des dll
    Par pepper dans le forum Installation, Déploiement et Sécurité
    Réponses: 4
    Dernier message: 23/01/2003, 22h34
  5. Visualisation des mise à jour en réseau
    Par fandor7 dans le forum Paradox
    Réponses: 2
    Dernier message: 06/12/2002, 15h54

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