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 :

datagrid group expand et ICollectionView.refresh()


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 249
    Par défaut datagrid group expand et ICollectionView.refresh()
    Salut à toutes et à tous,

    Je cherche depuis pas mal de temps et je ne trouve pas, or je suis sûr que je ne suis pas le premier à avoir besoin de cela.

    Soit un daragrid liée par son ItemsSource à une ICollectionView triée.

    Soit certains groupes étendus et d'autres refermés.

    Si je modifie une données via le code, le ICollectionView ne reste pas trié.

    Je dois donc faire un ICollectionView.refresh(), ce qui a pour effet de refermer (ou de rouvrir, selon comment ils sont défini par défaut) tous les groupes. Or j'ai besoin que les groupes resent comme ils étaient au moment du refresh (ou mieux, d'éviter de devoir faire le refresh parce que le ICollectionView resterait trié, mais à ce que j'ai lu ça n'a pas l'air possible).

    Merci de vos z'avis z'avisés,
    JM

  2. #2
    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 : 43
    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
    Par défaut
    Quelle version de .NET ? Depuis 4.5, WPF supporte le "live shaping", c'est à dire que le tri, les filtres et le groupement sont maintenus quand les données changent :
    http://msdn.microsoft.com/en-us/libr...x#live_shaping

    Par contre il faut l'activer explicitement

  3. #3
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 249
    Par défaut
    Merci tomlev,

    Ça fonctionne bien en général, mais dans un cas la mise à jour ne se fait pas.
    Il doit me manquer qqch mais je ne comprend pas ce qu'il me manque.

    Le datagrid est lié à une ObservableCollection de Matériel (dont la classe est écrite ci-dessous) à laquelle j'ai ajouté un LiveShaping.
    Le datagrid se précente comme suit :
    groupement de premier niveau sur la catégorie, et de second niveau sur la description
    les lignes standards montrent le détail, le dernier lieu et la date de dernier lieu de chaque matériel

    Quand il y a plusieurs matériels identiques, ils se classent donc dans le datagrid par LocalisationDate


    Si j'ajoute du matériel le live shaping fonctionne bien.

    Par contre, chaque matériel contient une autre ObservableCollection contenant un historique de lieu ainsi qu'une propriété LocalisationLieu (qui dit le dernier endroit où le matériel a été envoyé) et une popriété LocalisationDate (qui dit quand le matériel a été envoyé à LocalisationLieu). Si j'ajoute un élément dans cette liste, la datagrid ne se met pas à jour.
    Vu le codage de la classe Matériel, il me semble que lorsque j'ajouter une nouvelle localisation dans HistoriqueLocalisation, l'objet Matériel retourne une notification de modification, donc l'ObservableCollection ListeMatériel doit se mettre à jour via le live shaping.

    J'ai fais comme ceci :

    MainWindow.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
     
    ListeMatériel listeMatériel = new ListeMatériel();
    MatérielDataGrid.ItemsSource = listeMatériel;
     
     
    ICollectionView icvMatériels = CollectionViewSource.GetDefaultView(listeMatériel);
    icvMatériels.Culture = System.Globalization.CultureInfo.GetCultureInfo("fr-FR");
    if (icvMatériels != null && icvMatériels.CanGroup == true)
    {
        icvMatériels.GroupDescriptions.Clear();
        icvMatériels.GroupDescriptions.Add(new PropertyGroupDescription("Catégorie"));
        icvMatériels.GroupDescriptions.Add(new PropertyGroupDescription("Description"));
    }
    if (icvMatériels != null && icvMatériels.CanSort == true)
    {
        icvMatériels.SortDescriptions.Clear();
        icvMatériels.SortDescriptions.Add(new SortDescription("Catégorie", ListSortDirection.Ascending));
        icvMatériels.SortDescriptions.Add(new SortDescription("Description", ListSortDirection.Ascending));
        icvMatériels.SortDescriptions.Add(new SortDescription("Détails", ListSortDirection.Ascending));
        icvMatériels.SortDescriptions.Add(new SortDescription("LocalisationDate", ListSortDirection.Ascending));
    }
    ICollectionViewLiveShaping icvMatérielsLiveShaping = (ICollectionViewLiveShaping)CollectionViewSource.GetDefaultView(listeMatériel);
    icvMatérielsLiveShaping.IsLiveGrouping = true;
    icvMatérielsLiveShaping.IsLiveSorting=true;
    Classe Matériel
    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
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
     
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.IO;
    using System.Linq;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Text;
    using System.Threading.Tasks;
     
     
    namespace ApplicationQM
    {
        public class ListeMatériel : MatérielObservableCollection<Matériel>
        {
        }
     
     
        public class Catégories : CatégoriesObservableCollection<string>
        {
        }
     
     
        [Serializable]
        public class Matériel : INotifyPropertyChanged
        {
            private string catégorie;
            private string description;
            private string codeBarre;
            private string détails;
            private ObservableCollection<Localisation> historiqueLocalisation;
     
     
            public event PropertyChangedEventHandler PropertyChanged;
     
     
            /// <summary>
            /// Catégorie dans laquelle se trouve le matériel
            /// </summary>
            public string Catégorie
            {
                get { return catégorie; }
                set
                {
                    //Valeur par défaut
                    if (string.IsNullOrEmpty(value))
                        catégorie = "Autre";
                    else
                        catégorie = value;
                    OnPropertyChanged("Catégorie");
                }
            }
     
     
            /// <summary>
            /// Descritpion du matériel
            /// </summary>
            public string Description
            {
                get { return description; }
                set
                {
                    description = value;
                    OnPropertyChanged("Description");
                }
            }
     
     
            /// <summary>
            /// Code Barre du matériel
            /// </summary>
            public string CodeBarre
            {
                get { return codeBarre; }
                set
                {
                    codeBarre = value;
                    OnPropertyChanged("CodeBarre");
                }
            }
     
     
            /// <summary>
            /// Détails du matériel
            /// </summary>
            public string Détails
            {
                get { return détails; }
                set
                {
                    détails = value;
                    OnPropertyChanged("Dtails");
                }
            }
     
     
            /// <summary>
            /// Liste des mouvements du matériel
            /// </summary>
            public ObservableCollection<Localisation> HistoriqueLocalisation
            {
                get { return historiqueLocalisation; }
                set
                {
                    historiqueLocalisation = value;
                    ICollectionView hView = System.Windows.Data.CollectionViewSource.GetDefaultView(this);
                    OnPropertyChanged("HistoriqueLocalisation");
                    OnPropertyChanged("Localisation");
                    OnPropertyChanged("LocalisationDate");
                }
            }
     
     
            public object Localisation
            {
                get
                {
                    List<Localisation> sortedLst = this.HistoriqueLocalisation.OrderBy(x => x.DateMouvement).ToList();
                    Localisation dernièreLocalisation = sortedLst[sortedLst.Count - 1];
                    if (dernièreLocalisation.Endroit.GetType() == typeof(string))
                        return dernièreLocalisation.Endroit as string;
                    else
                        return dernièreLocalisation.Endroit as Personne;
                }
            }
     
     
            public DateTime LocalisationDate
            {
                get
                {
                    List<Localisation> sortedLst = this.HistoriqueLocalisation.OrderBy(x => x.DateMouvement).ToList();
                    return sortedLst[sortedLst.Count - 1].DateMouvement;
                }
            }
     
     
            #region Constructeurs
            /// <summary>
            /// Création d'un matériel vide. L'objet sera placé au QM avec de DateTime actuel
            /// </summary>
            public Matériel()
            {
                this.HistoriqueLocalisation = new ObservableCollection<Localisation> { new Localisation(DateTime.Now, "QM") };
            }
     
     
            /// <summary>
            /// Création d'un objet. L'objet sera placé au QM avec de DateTime actuel
            /// </summary>
            /// <param name="description">description du matériel</param>
            /// <param name="description">détails du matériel</param>
            /// <param name="catégorie">catégorie dans laquelle se trouve le matériel</param>
            /// <param name="codeBarre">code barre du matériel</param>
            public Matériel(string description, string détails = null, string catégorie = "Autre", string codeBarre = null)
            {
                this.Description = description;
                this.CodeBarre = codeBarre;
                this.Catégorie = catégorie;
                this.Détails = détails;
                this.HistoriqueLocalisation = new ObservableCollection<Localisation> { new Localisation(DateTime.Now, "QM") };
            }
     
     
            /// <summary>
            /// Création d'un objet
            /// </summary>
            /// <param name="description">description du matériel</param>
            /// <param name="dateMouvement">date à laquelle le matériel a été placé à sa localiation</param>
            /// <param name="description">détails du matériel</param>
            /// <param name="catégorie">catégorie dans laquelle se trouve le matériel</param>
            /// <param name="localisation">Endroit où est le matériel</param>
            /// <param name="codeBarre">code barre du matériel</param>
            public Matériel(string description, DateTime dateMouvement, string détails = null, string catégorie = "Autre", string localisation = "QM", string codeBarre = null)
            {
                this.Description = description;
                this.CodeBarre = codeBarre;
                this.Catégorie = catégorie;
                this.Détails = détails;
                this.HistoriqueLocalisation = new ObservableCollection<Localisation> { new Localisation(dateMouvement, localisation) };
            }
     
     
            /// <summary>
            /// Création d'un objet
            /// </summary>
            /// <param name="description">description du matériel</param>
            /// <param name="dateMouvement">date à laquelle le matériel a été attribué au Personne</param>
            /// <param name="description">détails du matériel</param>
            /// <param name="catégorie">catégorie dans laquelle se trouve le matériel</param>
            /// <param name="localisation">Personne chez qui est le matériel</param>
            /// <param name="codeBarre">code barre du matériel</param>
            public Matériel(string description, DateTime dateMouvement, Personne Personne, string détails = null, string catégorie = "Autre", string localisation = "QM", string codeBarre = null)
            {
                this.Description = description;
                this.CodeBarre = codeBarre;
                this.Catégorie = catégorie;
                this.Détails = détails;
                this.HistoriqueLocalisation = new ObservableCollection<Localisation> { new Localisation(dateMouvement, Personne) };
                Personne.Matériel.Add(this);
            }
            #endregion
     
     
            public void MouvementMatériel(DateTime dateMouvement, Personne personne)
            {
                List<Localisation> sortedLst = this.HistoriqueLocalisation.OrderBy(x => x.DateMouvement).ToList();
                Localisation dernièreLocalisation = this.HistoriqueLocalisation[sortedLst.Count - 1];
                if (this.Localisation.GetType() == typeof(Personne) && this.Localisation == personne)
                    throw new Exception(string.Format("Ce matériel est déjà détenu par cette Personne depuis le {0:dd MMM yyyy}", dernièreLocalisation.DateMouvement));
                this.HistoriqueLocalisation.Add(new Localisation(dateMouvement, personne));
                personne.Matériel.Add(this);
            }
     
     
            public void MouvementMatériel(DateTime dateMouvement, string localisation = "QM")
            {
                if (this.Localisation.GetType() == typeof(string) && this.Localisation.ToString() == localisation)
                    throw new Exception(string.Format("Ce matériel se trouve déjà à cet emplacement depuis le {0:dd MMM yyyy}", this.LocalisationDate));
                else if (this.Localisation.GetType() == typeof(Personne))
                    (this.Localisation as Personne).Matériel.Remove(this);
                this.HistoriqueLocalisation.Add(new Localisation(dateMouvement, localisation));
            }
     
     
            protected void OnPropertyChanged(string name)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                {
                    handler(this, new PropertyChangedEventArgs(name));
                }
            }
       }
     
     
        [Serializable]
        public class Localisation : IComparable
        {
            public Object Endroit { get; set; }
            public DateTime DateMouvement { get; set; }
     
            public Localisation(DateTime dateMouvement, string localisation)
            {
                this.DateMouvement = dateMouvement;
                this.Endroit = localisation;
            }
     
     
            public Localisation(DateTime dateMouvement, Personne personne)
            {
                this.DateMouvement = dateMouvement;
                this.Endroit = personne;
            }
     
     
            public override bool Equals(object obj)
            {
                if (obj == null) return false;
                Localisation localisation = obj as Localisation;
                if (localisation == null) return false;
                else return this.DateMouvement.Equals(localisation.DateMouvement);
            }
     
     
            public override int GetHashCode()
            {
                return base.GetHashCode();
            }
     
     
            public int SortByDateMouvementAscending(DateTime dateMouvement1, DateTime dateMouvement2)
            {
     
     
                return dateMouvement1.CompareTo(dateMouvement2);
            }
     
     
            public int SortByDateMouvementDescending(DateTime dateMouvement1, DateTime dateMouvement2)
            {
     
     
                return dateMouvement2.CompareTo(dateMouvement1);
            }
     
     
            // Comparaison par défaut.
            public int CompareTo(object compareLocalisation)
            {
                if (compareLocalisation.GetType() != typeof(Localisation))
                    throw new TypeAccessException("Le type ne correspond pas à Localisation");
                Localisation localisationAComprer = compareLocalisation as Localisation;
                return this.DateMouvement.CompareTo(localisationAComprer.DateMouvement);
            }
        }
     
     
        public class MatérielObservableCollection<T> : ObservableCollection<Matériel>
        {
            private static BinaryFormatter formatter = null;
     
     
            public void Save(string filePath)
            {
                List<Matériel> lstMatériel = this.ToList<Matériel>();
                System.Byte[] serialisedList;
                if (formatter == null) formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                using (MemoryStream stream = new MemoryStream())
                {
                    formatter.Serialize(stream, lstMatériel);
                    serialisedList = stream.ToArray();
                }
                File.WriteAllBytes(filePath, serialisedList);
            }
     
     
            public void LoadFromSavedFile(string filePath)
            {
                this.Clear();
                this.AddFromSavedFile(filePath);
            }
     
     
            public void AddFromSavedFile(string filePath)
            {
                if (File.Exists(filePath))
                {
                    System.Byte[] dbByte = File.ReadAllBytes(filePath);
                    List<Matériel> lstMatériel = new List<Matériel>();
                    if (formatter == null) formatter = new BinaryFormatter();
                    using (MemoryStream stream = new MemoryStream(dbByte))
                    {
                        lstMatériel = (List<Matériel>)formatter.Deserialize(stream);
                    }
                    foreach (Matériel matériel in lstMatériel)
                        this.Add(matériel);
                }
            }
        }
     
     
        public class CatégoriesObservableCollection<T> : ObservableCollection<string>
        {
            private static BinaryFormatter formatter = null;
     
     
            public new void Add(string catégorie)
            {
                if (this.Contains(catégorie))
                    throw new TypeAccessException("Cette catégorie est déjà existante.");
                base.Add(catégorie);
            }
     
            public void Save(string filePath)
            {
                List<string> lstCatégories = this.ToList<string>();
                System.Byte[] serialisedList;
                if (formatter == null) formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                using (MemoryStream stream = new MemoryStream())
                {
                    formatter.Serialize(stream, lstCatégories);
                    serialisedList = stream.ToArray();
                }
                File.WriteAllBytes(filePath, serialisedList);
            }
     
     
            public void AddFromSavedFile(string filePath)
            {
                if (File.Exists(filePath))
                {
                    System.Byte[] dbByte = File.ReadAllBytes(filePath);
                    List<string> lstCatégories = new List<string>();
                    if (formatter == null) formatter = new BinaryFormatter();
                    using (MemoryStream stream = new MemoryStream(dbByte))
                    {
                        lstCatégories = (List<string>)formatter.Deserialize(stream);
                    }
                    foreach (string catégorie in lstCatégories)
                        this.Add(catégorie);
                }
            }
        }
    }

  4. #4
    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 : 43
    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
    Par défaut
    Citation Envoyé par Jean-Marc68 Voir le message
    Vu le codage de la classe Matériel, il me semble que lorsque j'ajouter une nouvelle localisation dans HistoriqueLocalisation, l'objet Matériel retourne une notification de modification, donc l'ObservableCollection ListeMatériel doit se mettre à jour via le live shaping.
    Non, tu déclenches bien la notification quand on remplace HistoriqueLocalisation (dans le set de la propriété), mais pas quand on ajoute à la collection existante. Pour ça il faudrait que tu t'abonnes à l'évènement CollectionChanged de HistoriqueLocalisation, et que tu déclenches la notification pour les propriétés associées.

    De plus, il me semble (pas sûr) qu'il faut spécifier explicitement les propriétés prises en compte dans le live shaping (LiveSortingProperties, LiveFilteringProperties, LiveGroupingProperties).

  5. #5
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Mars 2007
    Messages : 249
    Par défaut
    Grrrr je n'y arrive pas.

    En cherchant j'ai trouvé ta classe PropertyChangedObservableCollection que j'ai utilisée à la place de ObservableCollection dans les cas suivants

    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 PropertyChangedObservableCollection<Localisation> historiqueLocalisation;
     
           public PropertyChangedObservableCollection<Localisation> HistoriqueLocalisation
            {
                get { return historiqueLocalisation; }
                set
                {
                    historiqueLocalisation = value;
                    ICollectionView hView = System.Windows.Data.CollectionViewSource.GetDefaultView(this);
                    OnPropertyChanged("HistoriqueLocalisation");
                    OnPropertyChanged("Localisation");
                    OnPropertyChanged("LocalisationDate");
                }
            }
    et j'ai modifié la classe Localisation pour la rendre notifiable
    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
    [Serializable]    
    public class Localisation : IComparable, INotifyPropertyChanged
        {
            private object endroit;
            private DateTime dateMouvement;
     
     
            public event PropertyChangedEventHandler PropertyChanged;
     
     
            public Object Endroit
            {
                get
                {
                    return endroit;
                }
                set
                {
                    endroit = value;
                    OnPropertyChanged("Endroit");
                }
            }
     
     
            public DateTime DateMouvement
            {
                get
                {
                    return dateMouvement;
                }
                set
                {
                    dateMouvement = value;
                    OnPropertyChanged("DateMouvement");
                }
            }
    ...
    J'admet avoir du mal à comprendre comment je devrais m'abonner à CollectionChanged pour que les modifs dans HistoriqueLocalisation notifier le parent (Matériel).

    il me semble (pas sûr) qu'il faut spécifier explicitement les propriétés prises en compte dans le live shaping (LiveSortingProperties, LiveFilteringProperties, LiveGroupingProperties).

    Je ne pense pas, parce que si j'ajoute un Matériel, le datagrid se met à jour "en live".

    Comme une image vaut 1000 mots, je joins un petit visu :
    Nom : ObservableCollectionQuestion.jpg
Affichages : 252
Taille : 30,3 Ko
    Comme je disais, si j'ajoute un matériel, le datagrid se met à jour. Par contre, si j'ajoute une localisation à une des boussoles, le datagrid ne se met pas à jour.
    J'ai remarqué aussi que lors de l'ajout d'
    une localisation à une des boussoles, on ne passe pas par le convertisseur qui compte le nombre d'éléments au QM. Le groupe reste notifié à "boussole (15 dont 15 au QM)" alors qu'elle aurait du passer à "boussole (15 dont 14 au QM)" et la boussole déplacée devrait avoir son lieu au nouveau lieu et sa date à la nouvelle date.

    Le convertisseur:
    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
    public class GroupsToTotalQMConverter : IValueConverter    {
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                //System.Diagnostics.Debugger.Break();
                Type test = value.GetType();
                if (value is System.Windows.Data.CollectionViewGroup && parameter is string)
                {
     
     
                    System.Windows.Data.CollectionViewGroup group = value as System.Windows.Data.CollectionViewGroup;
                    //return (value as MatérielObservableCollection<Matériel>).Count(x => x.Description == parameter.ToString() && x.Localisation.ToString() == "QM");
     
     
                    var items = (value as System.Windows.Data.CollectionViewGroup).Items;
                    Decimal totalQM = 0;
                    foreach (var item in items)
                    {
                        if (item is Matériel)
                        {
                            if (item != null && (item as Matériel).LocalisationLieu.ToString() == "QM")
                                totalQM++;
                            continue;
                        }
     
     
                        var lastLevel = item;
                        while (!(lastLevel as System.Windows.Data.CollectionViewGroup).IsBottomLevel)
                        {
                            lastLevel = (lastLevel as System.Windows.Data.CollectionViewGroup).Items;
                        }
                        ReadOnlyObservableCollection<Object> elements = (lastLevel as System.Windows.Data.CollectionViewGroup).Items;
                        foreach (var element in elements)
                        {
                            Matériel materiel = element as Matériel;
                            if (materiel != null && materiel.LocalisationLieu.ToString() == "QM")
                                totalQM++;
                        }
                    }
                    return totalQM.ToString();
     
     
                }
                return "0";
     
            }


    Par contre, tout fonctionne correctement si je fais un refresh sur le
    ICollectionView.

  6. #6
    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 : 43
    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
    Par défaut
    Citation Envoyé par Jean-Marc68 Voir le message
    En cherchant j'ai trouvé ta classe PropertyChangedObservableCollection que j'ai utilisée à la place de ObservableCollection dans les cas suivants
    Ma classe ? Ca me rappelle rien... tu as trouvé ça où ?

    Citation Envoyé par Jean-Marc68 Voir le message
    J'admet avoir du mal à comprendre comment je devrais m'abonner à CollectionChanged pour que les modifs dans HistoriqueLocalisation notifier le parent (Matériel).
    Abonne toi dans le setter (et n'oublie pas de te désabonner de l'ancienne collection) :

    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
             public ObservableCollection<Localisation> HistoriqueLocalisation
            {
                get { return historiqueLocalisation; }
                set
                {
                    if (historiqueLocalisation != null)
                        historiqueLocalization.CollectionChanged -= HistoriqueLocalizationCollectionChanged;
     
     
                    historiqueLocalisation = value;
                    historiqueLocalization.CollectionChanged += HistoriqueLocalizationCollectionChanged;
                    ICollectionView hView = System.Windows.Data.CollectionViewSource.GetDefaultView(this);
                    OnPropertyChanged("HistoriqueLocalisation");
                    OnPropertyChanged("Localisation");
                    OnPropertyChanged("LocalisationDate");
                }
            }
     
            private void HistoriqueLocalizationCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
            {
                // Notifier les propriétés qui dépendent du contenu de HistoriqueLocalisation
                OnPropertyChanged("Localisation");
                OnPropertyChanged("LocalisationDate");
            }

    Citation Envoyé par Jean-Marc68 Voir le message
    Je ne pense pas, parce que si j'ajoute un Matériel, le datagrid se met à jour "en live".
    Pour un nouvel élément oui, mais peut-être pas si tu modifies une propriété d'un élément existant

Discussions similaires

  1. MVVM, grid grouping expand/collaps ?
    Par ilanb dans le forum Ext JS / Sencha
    Réponses: 0
    Dernier message: 25/01/2015, 14h17
  2. Flex 2 : Grouping With DataGrid
    Par Sceener dans le forum Flex
    Réponses: 1
    Dernier message: 06/05/2010, 21h03
  3. Probleme Refresh Datagrid
    Par MrVentouse dans le forum Flex
    Réponses: 8
    Dernier message: 16/03/2010, 16h18
  4. [C#]datagrid & refresh
    Par manulemalin dans le forum ASP.NET
    Réponses: 2
    Dernier message: 04/12/2006, 10h14
  5. [VB.net] Refresh d'un datagrid au travers du dataAdapter
    Par WriteLN dans le forum Windows Forms
    Réponses: 5
    Dernier message: 14/06/2006, 10h39

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