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 :

ObservableCollection CollectionChanged ?


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Par défaut ObservableCollection CollectionChanged ?
    Bonjour,

    Encore un soucis et merci d'avance pour votre aide :

    J'utilise une requête linq pour récupérer certains champs de mon Entity (join de plusieurs tables)

    Le résultat est chargé dans une ObservableCollection POCO

    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
     
    public class CONTROLDATADEPO       
    {
                private int _seq_parametre;
                private string _code_port;
                public CONTROLDATADEPO(int m_seq_parametre, string m_codeport)
                {
                    _code_port= m_codeport;
                     _seq_parametre = m_seq_parametre;
                }
                public int SeqParametre
                {
                    get { return _seq_parametre; }
                    set { _seq_parametre = value; }
                }
                public string CodePort            
               {
                    get { return _code_port; }
                    set { _code_port = value; }
                }
    }

    Cette collection est chargée dans un Datagrid.
    (Je voudrais charger directement les champs à partir de mon Datagrid).

    Je dois enregistrer mes modifications dans ma base de données.
    Et donc j'aimerais savoir ce qui a changé dans mon observableCollection.

    D'après ce que j'ai lu, je dois m'abonner à l'évènement CollectionChanged, mais qui ne gérerait pas les Updates.

    Comment fait-on, svp?

    cdt

    Mickeybond

  2. #2
    Membre éclairé Avatar de koyot3
    Inscrit en
    Avril 2007
    Messages
    693
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 693
    Par défaut
    Salut Mickey,

    L'event collectionChanged ne va te notifier uniquement si ta collection change (ajout ou suppression par exemple) et pas une propriété d'un objet contenu dedans.

    Si tu veux être notifier, il faut t'abonner à l'event PropertyChanged de chaque objet contenu dedans (sous réserve que ces objet implémente INotifyPropertyChanged)

    En gros

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    foreach (CClass item in collect)
                {
                    item.PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged);
                }

    Après tu peux générer une classe héritant de ObservableCollection pour le faire.
    tomlev (membre du forum) a fait un super truc pour ça, voici son code :

    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
    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
    public class PropertyChangedObservableCollection<T> : ObservableCollection<T> where T : INotifyPropertyChanged
        {
            public PropertyChangedObservableCollection()
            {
            }
     
            public PropertyChangedObservableCollection(IEnumerable<T> collection)
                : base(collection)
            {
                foreach (var item in collection)
                {
                    if (item != null)
                        item.PropertyChanged += OnItemPropertyChanged;
                }
            }
     
            protected override void ClearItems()
            {
                var items = this.ToArray();
                base.ClearItems();
                foreach (var item in items)
                {
                    if (item != null)
                        item.PropertyChanged -= OnItemPropertyChanged;
                }
            }
     
            protected override void InsertItem(int index, T item)
            {
                base.InsertItem(index, item);
                if (item != null)
                    item.PropertyChanged += OnItemPropertyChanged;
            }
     
            protected override void RemoveItem(int index)
            {
                T item = Items[index];
                base.RemoveItem(index);
                if (item != null)
                    item.PropertyChanged -= OnItemPropertyChanged;
            }
     
            protected override void SetItem(int index, T item)
            {
                T oldItem = Items[index];
                base.SetItem(index, item);
                if (oldItem != null)
                    oldItem.PropertyChanged -= OnItemPropertyChanged;
                if (item != null)
                    item.PropertyChanged += OnItemPropertyChanged;
            }
     
            public event EventHandler<ItemPropertyChangedEventArgs<T>> ItemPropertyChanged;
     
            private void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                OnItemPropertyChanged((T)sender, e.PropertyName);
            }
     
            protected void OnItemPropertyChanged(T item, string propertyName)
            {
                var handler = ItemPropertyChanged;
                if (handler != null)
                    handler(this, new ItemPropertyChangedEventArgs<T>(item, propertyName));
            }
        }
     
        public class ItemPropertyChangedEventArgs<T> : PropertyChangedEventArgs
        {
            private readonly T _item;
     
            public ItemPropertyChangedEventArgs(T item, string propertyName)
                : base(propertyName)
            {
                _item = item;
            }
     
            public T Item
            {
                get { return _item; }
            }
        }

    Bon code

  3. #3
    Membre averti
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Par défaut
    Salut Koyot3

    j'ai récupéré la classe ... par contre la manière de s'abonner reste obscur.

    voici ce que j'ai fait :

    dans mon construteur du view model :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    (...)
    foreach (CONTROLDATADEPO item in m_DataDepo)
                {
                    item.PropertyChanged += new PropertyChangedEventHandler(IPC);
                }
    (...) 
     
    //puis j'ai ajouté l'évènement
     void IPC(object sender, PropertyChangedEventArgs e)
            {
                string toto = "tentative d'abonnement";
            }
    j'ai modifié ma classe CONTROLDATADEPO pour ajouter INotifyPropertyChanged
    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
     
    public class CONTROLDATADEPOSITAIRE : INotifyPropertyChanged 
            {
                private int _seq_parametre;
                private string _code_port;
     
                public CONTROLDATADEPO(int m_seq_parametre, string m_codeport)
                {
                    _code_port = m_codeport;
                    _seq_parametre = m_seq_parametre;
                }
                public int SeqParametre
                {
                    get { return _seq_parametre; }
                    set { _seq_parametre = value; }
                }
                public string CodePort            {
                    get { return _code_port; }
                    set { _code_port= value; }
                }
     
                public event PropertyChangedEventHandler PropertyChanged;
                protected void NotifyPropertyChanged(String info)
                {
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs(info));
                    }
                } 
            }

    Lorsque je change une cellule de mon Datagrid, je ne passe pas par l'évènement.

    Merci

  4. #4
    Membre éclairé Avatar de koyot3
    Inscrit en
    Avril 2007
    Messages
    693
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 693
    Par défaut
    Essai avec

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     public int SeqParametre
                {
                    get { return _seq_parametre; }
                    set { _seq_parametre = value; NotifyPropertyChanged("SeqParametre"); }
                }
                public string CodePort            {
                    get { return _code_port; }
                    set { _code_port= value;
    NotifyPropertyChanged("CodePort"); }
                }


  5. #5
    Membre averti
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Par défaut
    Génial ça marche

    Bon allez j'abuse encore un peu.

    Quelle solution adopter pour enregistrer les données dans ma base données?

    Maintenant que je suis abonné à l'évènement, j'imagine que je peux sauvegarder dans une liste uniquement les données qui ont changé puis lors d'une sauvegarde totale de mes données je les envoie en base.

    Est-ce la bonne méthode?

    merci

    Mickeybond

  6. #6
    Membre éclairé Avatar de koyot3
    Inscrit en
    Avril 2007
    Messages
    693
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 693
    Par défaut
    Je crois qu'avec Entity tu as un truc pour détecter les changements genre context.SaveChanges()

    Ou sinon tu as plusieurs solutions : ta méthode en est une !

    Ou mieux tu as un attribut IsModified de type bool dans tes objets. Tu le passes à true dès qu'il y a une modification.
    Ainsi quand tu veux sauvegarder, tu récupère tous les objets de la collection qui ont un IsModified == true et hop tu enregistres
    Et comme ça pas besoin de gérer l'abonnement à chaquun des items de ta collections...

    @+ sur les ondes

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

Discussions similaires

  1. [MVVM] implémentation de l’évènement CollectionChanged de ObservableCollection
    Par maradona_9 dans le forum Windows Presentation Foundation
    Réponses: 3
    Dernier message: 05/10/2012, 21h19
  2. ObservableCollection<T>.CollectionChanged à travers un ListCollectionView ?
    Par Chekov dans le forum Windows Presentation Foundation
    Réponses: 5
    Dernier message: 03/11/2009, 08h47
  3. ObservableCollection et liste de liste
    Par Anto03 dans le forum Windows Presentation Foundation
    Réponses: 1
    Dernier message: 06/11/2008, 10h14
  4. ObservableCollection serialisé en Generic.List avec CollectionDataContract
    Par amandinerenard dans le forum Windows Presentation Foundation
    Réponses: 1
    Dernier message: 25/03/2008, 11h02
  5. WCF probléme avec la serialisation de ObservableCollection
    Par amandinerenard dans le forum Windows Communication Foundation
    Réponses: 1
    Dernier message: 13/03/2008, 00h45

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