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

Silverlight Discussion :

MVVM, ListBox et ajout d'élément


Sujet :

Silverlight

  1. #1
    Invité
    Invité(e)
    Par défaut MVVM, ListBox et ajout d'élément
    Bonjour à tous,

    Je développe actuellement une application Silverlight. Cette application communique avec un Service WCF pour afficher une liste de clients.

    J'utilise le pattern MVVM.

    Au lancement de l'application, je charge une List de Client en récupérant les infos via WCF. Dès lors, les Clients apparaissent dans ma ListBox qui est bindé à la List de Client. Jusque là, rien de compliqué.

    Mon soucis vient quand j'essaye d'ajouter un élement (ou de supprimer) de ma List. Je m'attendais à ce que ma ListBox se mette à jour en conséquence en faisant apparaitre (ou disparaitre) le Client. Mais il ne se passe rien ... Le code qui ajoute l'élément est bien executé et j'ai contrôlé la taille de la List. Elle augmente bien.

    Je fais donc appel à vos lumières pour m'aider. Merci d'avance.

    Pour compléter mon message, voici les différents éléments de mon code :

    ViewModel - Command du bouton Ajouter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    commandNewCustomer = new RelayCommand(() =>
               {
                          MyCustomers.Add(new Customer() { etc ..... });
               }, () => true);
    ViewModel - Public Property
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public List<Customer> MyCustomers
            {
                get
                {
                    return myCustomers;
                }
                set
                {
                    myCustomers= value;
                    RaisePropertyChanged("MyCustomers");
                }
            }
    Et côté View :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    <ListBox Height="200" Margin="4,3,4,0" ItemTemplate="{StaticResource CustomerDataTemplate}" ItemsSource="{Binding MyCustomers}" SelectedItem="{Binding MySelectedCustomer, Mode=TwoWay}" >
    	<i:Interaction.Behaviors>
    		<ei:FluidMoveBehavior AppliesTo="Children"/>
    	</i:Interaction.Behaviors>
    </ListBox>
    En fait, pour qu'il se passe quelque chose côté UI, il faut que je fasse un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    MyCustomers= new List<Customer>();
    MyCustomers.Add(new Customer() { etc .... });
    Merci encore pour votre aide.

  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
    Utilise une ObservableCollection<Customer> plutôt qu'une List<Customer> si tu veux que ton interface graphique se mette à jour

  3. #3
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Thomas Lebrun Voir le message
    Utilise une ObservableCollection<Customer> plutôt qu'une List<Customer> si tu veux que ton interface graphique se mette à jour
    Hum, je vais tester ça demain.

    Mais le fait d'implémenter l'interface INotifyPropertyChanged, c'est pas supposé revenir au même ? J'ai cru que les deux méthodes étaient "équivalentes".

    Merci pour ta réponse en tout cas.

  4. #4
    Expert éminent sénior
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Points : 13 380
    Points
    13 380
    Par défaut
    Citation Envoyé par Hanki62 Voir le message
    Hum, je vais tester ça demain.

    Mais le fait d'implémenter l'interface INotifyPropertyChanged, c'est pas supposé revenir au même ? J'ai cru que les deux méthodes étaient "équivalentes".

    Merci pour ta réponse en tout cas.
    INotifyPropertyChanged c'est pour notifier qu'un propriété de ton objet a été modifié.

    Quand on utilise une collection et on veut que les items ajoutés/supprimés soit affichés en direct il faut utiliser une collection qui implémente INotifyCollectionChanged. Cette interface sert à notifier que la collection a été modifiée (ajout/suppression/modification/vidage).
    La classe ObservableCollection<T> l'implémente.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Skyounet Voir le message
    INotifyPropertyChanged c'est pour notifier qu'un propriété de ton objet a été modifié.

    Quand on utilise une collection et on veut que les items ajoutés/supprimés soit affichés en direct il faut utiliser une collection qui implémente INotifyCollectionChanged. Cette interface sert à notifier que la collection a été modifiée (ajout/suppression/modification/vidage).
    La classe ObservableCollection<T> l'implémente.
    Merci pour les précisions. Je connaissais pas l'interface INotifyCollectionChanged. Ça semble logique maintenant :p

  6. #6
    Invité
    Invité(e)
    Par défaut
    J'ai testé et, effectivement, ça fonctionne. L'élément apparait bien dans la ListBox. Par contre, il se place automatiquement à la fin.

    J'ai essayé de faire un OrderBy sur mon ObservableCollection mais ça ne change rien. J'aurais voulu que l'élément se place au bon endroit en respectant l'ordre d'une des propriétés (par exemple, Date du Client). C'est possible ?

    Enfin, j'ai une question concernant ce que Thomas m'a expliqué hier.

    Si je résume :
    Une List<T> implémente l'interface INotifyPropertyChanged.
    Une ObservableCollection<T> implémente l'interface INotifyCollectionChanged. Ce qui explique que l'interface graphique se mette à jour quand on fait des ajout, suppression, modif, ...

    Mais dans ce cas, pourquoi mon UI se mettait à jour hier lorsque je faisais ça sur ma List<T> :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    MyCustomers= new List<Customer>();
    MyCustomers.Add(new Customer() { etc .... });
    Je peux comprendre que l'UI se rafraîchisse avec la première ligne mais pourquoi le premier Client apparaît quand je fais un Add ? Il devrait être ignoré vu que la List n'implémente pas INotifyCollectionChanged !

    D'ailleurs, si je fais un nouveau Add dans une autre méthode (qui est exécutée sur le click d'un bouton par exemple), il n’apparaîtra pas cette fois. Quelle est la différence ?

    Merci d'avance.

  7. #7
    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 Hanki62 Voir le message
    Une List<T> implémente l'interface INotifyPropertyChanged.
    Non, c'est T qui implémente INotifyPropertyChanged: List n'implémente que les interfaces spécifiques aux listes, c'est tout

    Une ObservableCollection<T> implémente l'interface INotifyCollectionChanged. Ce qui explique que l'interface graphique se mette à jour quand on fait des ajout, suppression, modif, ...
    Oui

    Pour le reste, c'est en effet étrange que ta vue se soit mise à jour, même avec une List...

    Si tu veux trier tes éléments, tu peux essayer:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MonObservableCollection<T>.Add(MonElement());
    MonObservableCollection = MonObservableCollection.OrderBy(e => e.Name);

  8. #8
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Thomas Lebrun Voir le message
    Non, c'est T qui implémente INotifyPropertyChanged: List n'implémente que les interfaces spécifiques aux listes, c'est tout
    Oui, tu as raison


    Oui

    Pour le reste, c'est en effet étrange que ta vue se soit mise à jour, même avec une List...
    Très étrange


    Si tu veux trier tes éléments, tu peux essayer:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MonObservableCollection<T>.Add(MonElement());
    MonObservableCollection = MonObservableCollection.OrderBy(e => e.Name);
    C'est ce que j'ai fais et ça fonctionne

    Merci encore.

  9. #9
    Expert éminent sénior
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Points : 13 380
    Points
    13 380
    Par défaut
    Pour le tri, tu peux passer par une CollectionViewSource et ajouter un SortDescription. Le tri se fera tout seul.

  10. #10
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Mais dans ce cas, pourquoi mon UI se mettait à jour hier lorsque je faisais ça sur ma List<T>
    Pour le reste, c'est en effet étrange que ta vue se soit mise à jour, même avec une List...
    Est-ce que par hasard cette List<T> ne serait pas initialisée avant l'appel à InitializeComponent ?

  11. #11
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par seriousme Voir le message
    Est-ce que par hasard cette List<T> ne serait pas initialisée avant l'appel à InitializeComponent ?
    Cette liste est initialisée dans le ViewModel du MainPage.
    Le code en question était executée sur une Command (bindée à mon bouton).

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

Discussions similaires

  1. [MVVM] Détecter l'ajout d'un élément sur une liste
    Par Digilougm dans le forum Silverlight
    Réponses: 10
    Dernier message: 16/06/2011, 11h10
  2. [ListBox] Ajout d'élément
    Par orfix dans le forum Windows Presentation Foundation
    Réponses: 11
    Dernier message: 25/06/2009, 17h00
  3. Réponses: 3
    Dernier message: 25/01/2009, 17h32
  4. [VB.Net 2005]Ajouter un élément à une listbox
    Par DonF dans le forum Windows Forms
    Réponses: 2
    Dernier message: 27/09/2006, 13h07
  5. Ajouter des éléments à ListBox
    Par priest69 dans le forum Access
    Réponses: 5
    Dernier message: 20/09/2005, 14h05

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