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 :

Gérer l'annulation des modifications


Sujet :

Windows Presentation Foundation

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Novembre 2006
    Messages : 107
    Points : 51
    Points
    51
    Par défaut Gérer l'annulation des modifications
    Salut,

    C'est mon premier projet avec WPF.
    Suite aux lectures sur les blogs et MSDN, je mets en place un modèle MVVM.
    Je me demande comment gérer l'annulation des modifications sur un objet.

    Dois-je gérer une copie de mon objet afin de pouvoir annuler les modifications quand l'utilisateur cliquera sur un bouton "Annuler" de mon panel d'édition de l'objet.

    Par exemple, pour l'édition d'un objet de classe MyData, je crée une classe MyDataVM contenant l'objet édité et sa copie. Ma vue est bindée sur les propriétés de l'objet editedState.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    class MyData{....}
     
    class MyDataVM : ViewModelBase{
      MyData initialState;
      MyDate editedState;
    }
    Ne me tapez pas , ce n'est qu'une proposition car je vois pas bien comment gérer proprement l'annulation de modification sur un bean...

    Merci de votre aide et de tous vos conseils ou liens que vous pourrez m'apporter

  2. #2
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut
    Si tu veux opuvoir gérer l'annulation, regarde du coté de l'interface IEditableObject

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Novembre 2006
    Messages : 107
    Points : 51
    Points
    51
    Par défaut
    Merci Thomas.

    Ca semble en effet répondre complétement à mes besoins.

    Pour test, j'ai fait une classe Personne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Person
    {
            public string Nom { get; set; }
            public string Prenom { get; set; }
            public int Age { get; set; }
    }
    Et dans le ViewModel associé PersonVM:
    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
    class PersonVM:EditableAdapter<Person>
        {
            public PersonVM(Person p) : base(p) {
                BeginEdit();
            }
     
     
            private ICommand _cancelCmd;
            public ICommand CancelCommand
            {
                get
                {
                    if (_cancelCmd == null)
                        _cancelCmd = new RelayCommand<Window>(
                            w => Cancel(w),
                            w => CanCancel);
     
                    return _cancelCmd;
                }
            }
     
            private bool CanCancel
            {
                get
                {
                    return true;
                }
            }
     
            private void Cancel(Window w)
            {
                if (this.CanCancel)
                {
                   // w.Close();
                    CancelEdit();
                }
            }
    Et le xaml:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <TextBox Name="nameTb" Grid.Row="0" Grid.Column="1" Text="{Binding Path=Nom}"/>
    <TextBox Name="firstnameYTb" Grid.Row="1" Grid.Column="1" Text="{Binding Path=Prenom}"/>
    Ca marche bien.

    Mais comment gérer le fait qu'un objet est un agrégat d'autres objets ?
    Exemple en intégrant une classe Identity dans Person :
    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
    class Identity
        {
            public Identity()
            {
                Nom = "Inconnu";
                Prenom = "Inconnu";
            }
            public string Nom { get; set; }
            public string Prenom { get; set; }
        }
     
    class Person
        {
            public Person()
            {
                Identite = new Identity();
            }
            public Identity Identite { get; set; }
            public int Age { get; set; }
        }
    La classe PersonVM est inchangée.

    Le xaml est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <TextBox Name="nameTb" Grid.Row="0" Grid.Column="1" Text="{Binding Path=Identite.Nom}"/>
    <TextBox Name="firstnameYTb" Grid.Row="1" Grid.Column="1" Text="{Binding Path=Identite.Prenom}"/>
    Du coup si je modifie les noms et prénoms sur l'ihm, les changements sont définitifs. Il n'y a pas de CancelEdit sur l'objet Identity.

    Comment puis-je gérer cela élégamment ?
    Faut-il créer une classe ViewModel pour la classe Identity ?
    Comment modifier alors PersonVM en conséquence ?

    Je vois pas là ....
    Merci de votre aide

  4. #4
    Membre régulier
    Profil pro
    Développeur informatique
    Inscrit en
    Mai 2008
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2008
    Messages : 77
    Points : 78
    Points
    78
    Par défaut
    Hello,

    Pour résoudre ton problème, tu devrais commencer par prendre tous tes objets qui doivent supporter une annulation d'édition et les faire hériter de IEditableObject comme mentionné plus haut (dans ton cas, ca serait les objets Person et Identity).

    Par contre, ces capacités offerte par IEditableObject à tes objets ne sont intéréssantes (si je ne dis pas de betise) que lorsque tu utilises un BindingGroup.

    Le BindingGroup permet en gros de faire une validation en bloc. Il possède aussi, entre autres, une méthode nommée 'CancelEdit'. Lorsque cette méthode est appelée, c'est le BindingGroup qui se chargera d'appeler les méthodes 'CancelEdit' de tes objets et du coup tu n'a plus rien à faire.

    J'espère que ca pourrait t'aider.

    Riana

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Novembre 2006
    Messages : 107
    Points : 51
    Points
    51
    Par défaut
    Merci beaucoup pour ces éléments de réponses
    Ca me parait très très bien tout ca !!!
    Je regarde cela de plus près.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Novembre 2006
    Messages : 107
    Points : 51
    Points
    51
    Par défaut
    Citation Envoyé par Whisperer Voir le message
    Hello,

    Pour résoudre ton problème, tu devrais commencer par prendre tous tes objets qui doivent supporter une annulation d'édition et les faire hériter de IEditableObject comme mentionné plus haut (dans ton cas, ca serait les objets Person et Identity).

    Par contre, ces capacités offerte par IEditableObject à tes objets ne sont intéréssantes (si je ne dis pas de betise) que lorsque tu utilises un BindingGroup.

    Le BindingGroup permet en gros de faire une validation en bloc. Il possède aussi, entre autres, une méthode nommée 'CancelEdit'. Lorsque cette méthode est appelée, c'est le BindingGroup qui se chargera d'appeler les méthodes 'CancelEdit' de tes objets et du coup tu n'a plus rien à faire.

    J'espère que ca pourrait t'aider.

    Riana
    J'ai donc regardé du côté du BindingGroup. C'est très intéressant et je vais vraisemblablement l'utiliser.
    Par contre, j'ai toujours un problème.

    Imaginons qu'une personne possède un véhicule.
    Le véhicule pouvant être soit une moto, soit une voiture...

    J'ai donc fait le modèle de données suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class Personne{ 
    string nom {get;set;} 
    Vehicule {get; set;}
    }
    abstract class Vehicule{}
    class voiture: Vehicule{}
    class moto : Vehicule{}
    La vue modèle est la suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    class PersonVM:EditableAdapter<Person>{...}
    class VoitureVM:EditableAdapter<Voiture>{...}
    class MotoVM:EditableAdapter<Moto>{...}
    Et là je vois pas bien comment je vais pouvoir gérer à la fois que l'utilisateur peut modifier/annuler les propriétés du véhicule et à la fois pouvoir changer de véhicule
    Bref, où et quand créer VoitureVM/MotoVM ? que faire sur le EndEdit de PersonneVM ???

    Je suis perdu
    please help

  7. #7
    Membre régulier
    Profil pro
    Développeur informatique
    Inscrit en
    Mai 2008
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2008
    Messages : 77
    Points : 78
    Points
    78
    Par défaut
    Par rapport au problème que tu poses, si j'ai bien compris, PersonneVM possède donc en réalité une propriété nommée Vehicule qui est elle même de type Vehicule (donc peut etre une moto ou une voiture).

    Si tu veux gérer l'annulation du changement de la propriété Vehicule, qui se trouve sur la classe PersonneVM, il te suffit d'implémenter la méthode 'CancelEdit' (que tu dois avoir si ton objet PersonneVM hérite de IEditableObject).

    Pour l'appel de cette méthode, ca sera l'appel a BindingGroup.CancelEdit qui s'en chargera si tu l'appelles plus tard ...

  8. #8
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut
    Citation Envoyé par Whisperer Voir le message
    les faire hériter de IEditableObject comme mentionné plus haut
    Juste un petit détail: une classe n'hérite pas d'une interface, elle l'implémente

  9. #9
    Membre régulier
    Profil pro
    Développeur informatique
    Inscrit en
    Mai 2008
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2008
    Messages : 77
    Points : 78
    Points
    78
    Par défaut
    Ah ces puristes alors ! Mais tu as raison, il vaut mieux être précis dans les termes.

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Novembre 2006
    Messages : 107
    Points : 51
    Points
    51
    Par défaut
    Re salut

    Après quelques semaines d'interruption, je me repenche sur ce projet...
    Bon maintenant c'est ok pour gérer les annulations sur un objet (grace à IEditableObject et un adapter par dessus..).

    Par contre, j'ai un soucis avec les listes.
    J'ai une table bindée sur une liste d'objet. J'ai utilisé ListCollectionView. C'est pas mal la gestion du commit et du cancel sur ListCollectionView mais ca gère le cancel que sur un élément.
    Je m'explique...

    Je peux faire plusieurs AddNew sur ma liste mais le CancelNew n'annule que le dernier new.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MyList.AddNew();
    MyList.AddNew();
    MyList.AddNew();
    MyList.CancelNew();
    //MyList contient alors 2 éléments
    Est-ce moi qui fait un mauvais usage de ListCollectionView ?

Discussions similaires

  1. Réponses: 1
    Dernier message: 21/10/2010, 15h46
  2. [Toutes versions] Comment gérer l'historique des modifs
    Par balzanito dans le forum Modélisation
    Réponses: 3
    Dernier message: 06/12/2009, 09h36
  3. Binding forms - annulation des modifs
    Par thorgal1612 dans le forum Windows Forms
    Réponses: 5
    Dernier message: 07/07/2009, 17h27
  4. Annuler des modifications sur BindingSource.Current
    Par BnJ99 dans le forum Framework .NET
    Réponses: 3
    Dernier message: 29/06/2007, 14h34
  5. [formulaire] Annuler des modifications
    Par stéphane_ais2 dans le forum IHM
    Réponses: 5
    Dernier message: 24/11/2006, 12h00

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