[WPF]TreeView, Collection

Résolu
CH4BRN Messages postés 51 Date d'inscription lundi 19 février 2018 Statut Membre Dernière intervention 6 février 2021 - 27 mars 2018 à 16:21
CH4BRN Messages postés 51 Date d'inscription lundi 19 février 2018 Statut Membre Dernière intervention 6 février 2021 - 29 mars 2018 à 14:41
Bonjour,

Dans un projet, j'ai une DataGrid qui affiche le contenu (par Binding) d'une ObservableCollection contenant des Objets "Logs" possédant eux même diverses propriétés (Type, Date, Thread, etc.).

Aucun problème pour l'affichage du DataGrid :
<DataGrid 
FontSize="15" Margin="5" Grid.Column="0"  Grid.Row="10" Grid.ColumnSpan="6" Width="Auto" MaxHeight="460" ItemsSource="{Binding Path=CollectedLogs, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectionMode="Single" 
SelectedValue="{Binding SelectedValue, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" 
SelectedItem="{Binding SelectedRow, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />



je voudrais, au clic sur une des lignes du DataGrid, afficher dans une autre vue un TreeView présentant une arborescence par dates des objets correspondant à la ligne sélectionnée.

J'ai envoyé et récupéré ma Collection originelle et ma valeur sélectionnée grâce à des PubSubEvent :

Page 1 :
  public void navigateToTreeView(Log selectedRow)
        {
            this.RegionManager.RequestNavigate(RegionNames.MainRegion, "PRJ_LogReader.Views.DisplayTreeView");
            this.EventAggregator.GetEvent<PubSubEvent<Log>>()
                .Publish(selectedRow);
            this.EventAggregator.GetEvent<PubSubEvent<ObservableCollection<Log>>>()
                .Publish(CollectedLogs);
        }

Page 2 :
public void OnResponse(Log log)
        {
            ReceivedLog = log;
            
            ReceivedLogSession = ReceivedLog.Session;
            Console.WriteLine("received session = " + ReceivedLog.Session);
            ReceivedDate = ReceivedLog.DateAndTime;
            Console.WriteLine("ReceivedDate = " + ReceivedDate);
        }

        public void OnResponse(ObservableCollection<Log> collectedLogs)
        {
            Collection = collectedLogs;
            Console.WriteLine("Coll session = " + Collection[0].Session);
            Console.WriteLine("ItemsCount = " + Items.Count);
        }


Mais pour afficher ce que je veux dans un TreeView, je galère !

J'ai réussi à faire ceci :
J'ai une classe "TreeLog" comportant trois éléments, un string "name", une liste de Log "ListedLogs" et une IList de TreeLog intitulée "Children".
Je voulais remplir une nouvelle ObservableCollection, ou une liste, bindée à mon TreeView, avec cette methode :

public static List<TreeLog> GetChild ( List<Log> logs, DateTime key)
{
var hierarchicalLog = new List<TreeLog>();
var items = logs.Where( w => w.Date == key).ToList();

foreach ( var item in items)
{
 var LogTreeView = new TreeLog
 {
  Name = item.Name,
  Date = key,
  Children = new List<TreeLog>()
 };

 var itemKey = logs.IndexOf(item);
 if ( itemKey + 11 < logs.count -1)
 {
  var nextKey = log[itemKey + 1].Date;
  LogTreeView.Children = getChild(logs, nextKey);
 }
 hierarchicalLog.Add(LogTreeView);
}
return hierarchicalLog;
}


Mais j'ai une exception StackOverflow.
J'ai du mal à comprendre pourquoi, vous pouvez m'aider?

Merci infiniment !

3 réponses

Whismeril Messages postés 18425 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 9 juin 2023 624
28 mars 2018 à 23:28
Bonsoir
Peux tu envoyer un fichier de logs representatif de la réalité sans données confidentielles et qui déclenche l’erreur?
A mon avis tu boucles « à l’infini », mais il faut faire des tests pour être sûr.
0
CH4BRN Messages postés 51 Date d'inscription lundi 19 février 2018 Statut Membre Dernière intervention 6 février 2021
29 mars 2018 à 09:31
Bonjour
je pense que ça ne vaut pas le coup d'envoyer un fichier, ils sont toujours composés de la même manière :
Des lignes comme suit :

chaine de 5 lettres ; date au format AAAA-MM-DD HH:mm:ss,fff ; 5 chiffres ; deux chiffres ; chaine de 90 caractères; chaine de 6 caractères ;;;; 1chiffre;chaine de 24 caractères;Chaine de 11 caractères;6 chiffres;6 chiffres;Chaine de 21 caractères;;chaine de 90 caractères;


les propriétés sont séparées par des points virgules, et aléatoirement, la ligne de titre suivante
Type;Date;Temps;Thread;Propriétés;Produit;Fichier;Classe;Méthode;Ligne;Session;Module;Utilisateur;Elément de structure;;Action;

se répète, mais je l'ignore sans problème.

Je me suis rendu compte que j'avais des doublons parce que j'ai bêtement dupliqué des lignes pour avoir plus de "matière".
J'ai donc modifié mon algo de lecture de fichier pour qu'ils ignore les lignes qui sont déjà présentes dans la collection, je vais réessayer tout ça ce matin, et je reviendrais probablement vers vous, après avoir échoué ! :)

Bonne matinée à vous.
0
CH4BRN Messages postés 51 Date d'inscription lundi 19 février 2018 Statut Membre Dernière intervention 6 février 2021
29 mars 2018 à 10:51
Bon après élimination des doublons, il semblerait que la malfaisante Stack Overflow ne soit plus qu'un mauvais souvenir. Mais mon TreeView n'affiche plus rien..

Si tu/vous avez encore la motivation pour m'aider, je suis preneur.


Mon algo actuel :
    private List<TreeLog> GetChild(List<Log> logs, DateTime key)
        {
            var hierarchicalLog = new List<TreeLog>();

            var items = logs.Where(w => w.DateAndTime == key).ToList();

            Console.WriteLine("items Count = " + items.Count);

            foreach (var item in items)
            {
                Console.WriteLine("Creating new treeLog");
                var treeLog = new TreeLog
                {
                    Name = item.DateAndTime.ToShortDateString() + "." + item.DateAndTime.ToLongTimeString() + "." + item.DateAndTime.Millisecond,
                    Date = key,
                    Children = new List<TreeLog>()
                };

                Console.WriteLine("TreeLog name = " + treeLog.Name);
                

                var itemKey = logs.IndexOf(item);
                Console.WriteLine("itemKey = " + itemKey);
                
                var itemKeyPlusOne = itemKey +1;
                Console.WriteLine("itemKeyPlusOne = " + itemKeyPlusOne);
                
                var logsCountMinusOne = (logs.Count - 1);
                Console.WriteLine("logsCountMinusOne = " + logsCountMinusOne);


                

                if (itemKeyPlusOne < logsCountMinusOne)
                {
                    Console.WriteLine(itemKeyPlusOne + " < " + logsCountMinusOne);
                    
                    var nextKey = logs[itemKeyPlusOne].DateAndTime;

                    Console.WriteLine("nextKey = " + nextKey +"."+ nextKey.Millisecond);
                    Console.WriteLine("Key = " + key+"." + key.Millisecond);

                    
                    treeLog.Children = GetChild(logs, nextKey);
                    Console.WriteLine("treeLogChildrenCount = " + treeLog.Children.Count);
                    
                }
                
                hierarchicalLog.Add(treeLog);
                
            }
           // Console.WriteLine("hierarchicalLog count = " + hierarchicalLog.Count);
            return hierarchicalLog;

        

        }


Pour éliminer mes doublons, j'ai fais un Group by :
var distinctLogs = CollectedLogs.GroupBy(log => log.DateAndTime)
                        .Select(group => group.First());


Mais apparement, ce serait plus interessant et "propre" d'implémenter IComparable.
Désolé, je digresse. :)
0
CH4BRN Messages postés 51 Date d'inscription lundi 19 février 2018 Statut Membre Dernière intervention 6 février 2021
29 mars 2018 à 14:41
Voila, enfin, j'ai mon TreeView affiché, tout "va bien", je vais pouvoir creer un autre sujet pour un autre problème.
 : D 
0