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 :

List<T>, Linq, Binding, XAML et perte de la référence d'objet ?


Sujet :

C#

  1. #1
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut List<T>, Linq, Binding, XAML et perte de la référence d'objet ?
    Bonjour,

    J'ai une liste "List<Valeur>" qui contient une collection d'instance de Valeur.

    J'ai une Page qui contient un ListView dont le ItemsSource est un sous-ensemble de ma liste :
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    List<Valeur> Valeurs = new List<Valeur>();
     
    Valeurs.Add(...);
     
    listValeurs.ItemsSource = Valeurs.Where(valeur => valeur.MaProprieteQuiVaBien <= 6);

    Ensuite, sur le double-tap de la ListView, je navigue vers une autre Page, en passant l'item sélectionné en paramètre, qui est une référence à une ligne de ma List<Valeur> :
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
            private void listValeurs_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
            {
                Frame.Navigate(typeof(Detail), (sender as ListView).SelectedItem as Valeur);
            }

    Et je récupère ensuite dans ma page Detail :
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                valeur = e.Parameter as Valeur;
                txtValeur.Text = valeur.MaProprieteQuiVaBien.ToString();
                base.OnNavigatedTo(e);
            }

    Je met ensuite à jour mon objet "valeur", qui est, selon moi, une référence à l'objet reçu en paramètre, donc toujours lié à mon List<Valeur> de la page principale :
    Code csharp : 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
     
            private void btnSave_Click(object sender, RoutedEventArgs e)
            {
                msgError.Text = string.Empty;
                StringBuilder sb = new StringBuilder();
     
                int val = -1;
                if (!int.TryParse(txtValeur.Text, out val))
                {
                    sb.Append("La valeur doit être un nombre entier positif\n"); 
                }
                else if (val < 1)
                {
                    sb.Append("La valeur doit être un nombre entier positif\n");
                }
     
                msgError.Text = sb.ToString();
                if (msgError.Text.Length > 0)
                {
                    return;
                }
                else
                {
                    valeur.MaProprieteQuiVaBien = val;
                    Frame.GoBack();
                }
            }
        }

    Et là, retour sur la page principale : la propriété de l'objet que j'ai modifié n'est pas mise à jour.
    Qu'à cela ne tienne, je me dis que c'est un souci de refresh qui ne s'est pas fait. Après tout, le binding, ça marche quand ça veut...

    Je réouvre le détail, et je retrouve la valeur avant modification.

    J'en déduis qu'à un moment, au lieu de passer mon "Valeur" par référence, il le passe par valeur, et du coup je modifie non pas l'instance qui se trouve dans mon List<Valeur>, mais une copie... seulement c'est à quel moment qu'à lieu cette recopie ? Comment l'en empêcher ?
    On ne jouit bien que de ce qu’on partage.

  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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    Après tout, le binding, ça marche quand ça veut...
    Non, ça marche quand on l'utilise bien

    Citation Envoyé par StringBuilder Voir le message
    J'en déduis qu'à un moment, au lieu de passer mon "Valeur" par référence, il le passe par valeur, et du coup je modifie non pas l'instance qui se trouve dans mon List<Valeur>, mais une copie... seulement c'est à quel moment qu'à lieu cette recopie ? Comment l'en empêcher ?
    Si Valeur est une classe (type référence), il n'est même pas possible de le passer par valeur (à moins de le cloner explicitement, ou de le sérialiser/désérialiser). Donc non, c'est bien une référence qui est passée.

    Par contre, est-ce que Valeur implémente bien INotifyPropertyChanged ? C'est une condition essentielle pour que les modifications soient prises en compte par le binding.

  3. #3
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Ok.

    En attendant ta réponse, j'ai modifié légèrement le programme.
    => Je suis passé par un singleton qui gère mon List<T> (c'était de toute façon nécessaire, car mon List<T> est partagé dans l'ensemble du programme).

    Du coup, je manipule directement le singleton en utilisant l'index, et le problème a été résolu.

    Je garde dans un coin le coup du INotifyPropertyChanged.

    Ceci dit, je ne vois pas trop ce que ça va changer.

    Car mon List<T> n'était de toute façon pas modifié (indépendamment du faire que la liste soit rafraîchie ou non).
    On ne jouit bien que de ce qu’on partage.

  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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    => Je suis passé par un singleton qui gère mon List<T> (c'était de toute façon nécessaire, car mon List<T> est partagé dans l'ensemble du programme).
    Mouais... l'utilisation d'un singleton dans ce genre de cas, c'est juste une façon déguisée de faire une variable globale.

    Il vaudrait mieux encapsuler cette liste dans un service que tu injectes dans chaque page.

    Citation Envoyé par StringBuilder Voir le message
    Je garde dans un coin le coup du INotifyPropertyChanged.

    Ceci dit, je ne vois pas trop ce que ça va changer.
    Bah ça va changer que c'est ça qui va notifier le binding qu'il doit se rafraichir...

    Citation Envoyé par StringBuilder Voir le message
    Car mon List<T> n'était de toute façon pas modifié (indépendamment du faire que la liste soit rafraîchie ou non).
    Ce n'est pas le problème ; c'est pas la liste qui est modifiée, mais un élément de la liste. C'est pour ça que cet élément doit implémenter INotifyPropertyChanged.

    Soit dit en passant, si tu bindes directement ta vue sur une List<T>, ça ne se rafraichira pas si tu ajoutes ou supprimes des éléments. Il faut utiliser ObservableCollection<T> à la place.

  5. #5
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Bah pourtant, là, comme ça, ça marche. (Application Windows 10 Universelle).

    Je bind ma liste dans un ListView.
    Quand je double clique sur un élément, j'ouvre une page de détail.
    Quand je modifie le détail et que je ferme la fenêtre fille, la ListView contient bien la liste mise à jour.

    Après, je sais pas ce que fait le programme "par derrière", notamment quand on réaffiche la première fenêtre, peut-être qui relance tout son code... J'espère que non
    On ne jouit bien que de ce qu’on partage.

Discussions similaires

  1. [MVVM] Binding xaml sur une List/ObserveableCollection du Model plutôt que sur une propriété du Model
    Par uluquiorra dans le forum Windows Presentation Foundation
    Réponses: 4
    Dernier message: 21/11/2012, 18h43
  2. Dependency property et Binding XAML
    Par PPierre59 dans le forum Silverlight
    Réponses: 3
    Dernier message: 15/06/2010, 23h46
  3. Réponses: 1
    Dernier message: 22/12/2009, 20h05
  4. Binding XAML : typer un SelectedItem
    Par Goj17 dans le forum Windows Presentation Foundation
    Réponses: 16
    Dernier message: 30/04/2008, 12h41
  5. problème binding xaml
    Par cyberchand dans le forum C#
    Réponses: 6
    Dernier message: 14/02/2007, 16h10

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