2010-07-21 8 views
2

Je ObservableCollection affecté aux personnes et ont une PersonViewModel et un PeopleViewModelComment rafraîchir une ListItem dans WPF ListView, CollectionViewSource dans MVVM

_people = GetAll().ToList(); 
List<PersonViewModel> allPeople = (from person in _people 
            select new PersonViewModel(person)).ToList(); 
AllPeople = new ObservableCollection<WorkOrderListItemViewModel>(allOrders); 
AllPeopleCollection.Source = AllPeople; 


AllPeopleCollection est une propriété publique de type CollectionViewSource et
AllPeople est une propriété publique de type ObservableCollection

Je dois modifier l'icône que j'utilise pour une ligne dans une liste en cliquant sur cet élément. Mais pour mettre à jour la vue, j'ai besoin de lire toute la liste à nouveau. Comme ma liste contient plus de 100 enregistrements, il faut beaucoup de temps pour actualiser la liste.

Y at-il un moyen que je peux seulement actualiser un élément particulier dans la liste et l'actualiser sur l'interface utilisateur.

+2

Je crois que si vos articles eux-mêmes mettre en œuvre INotifyPropertyChanged, cela devrait corriger. – Firoso

Répondre

3

oui, vos PersonViewModel devraient mettre en œuvre INotifyPropertyChanged et augmenter l'événement PropertyChanged dans le setter de la propriété de l'icône (il est soulevé automatiquement après chaque mise à jour). Cela déclenchera une actualisation de l'interface graphique si vos liaisons sont correctes.

code:

public class PersonViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private YourIconType _Icon; 
    public YourIconType Icon 
    { 
     get { return _Icon; } 
     set 
     { 
      _Icon = value; 
      if (PropertyChanged != null) 
       PropertyChanged.Invoke(this, 
        new PropertyChangedEventArgs("Icon")); 
     } 
    } 
} 
+0

Je suis déjà en train de l'implémenter dans ma classe de base .. et de déclencher le Onproperty modifié pour la collection – crazy9

+1

oui, mais cela se met à jour si la collection elle-même change (si un élément est ajouté ou supprimé) et non unique si la propriété d'un changements d'article. – andyp

0

Tout d'abord, votre nombre record est vraiment rien en face de ListView WPF comme il utilise VirtualizingStackPanel. En plus de la solution exacte de la notification PropertyChange, vous devriez également considérer le concept deferred execution. Vous semblez tout convertir en une liste qui conduirait à l'énumération forcée de l'ensemble de résultats à la fois.

Considérons votre code:

_people= GetAll().ToList(); 
//The result of GetAll is enumerated and a solid list is created 

List<Person> allPeople = (from person in _people 
          select new PersonViewModel(person)).ToList(); 
// another list created 

AllPeople = new ObservableCollection<PersonViewModel>(allPeople); 
// ObservableCollection created out of list 

Laissez-nous modifions un peu:

_people= GetAll(); // The result is just referred by _people 

IEnumerable<Person> allPeople = (from person in _people 
           select new PersonViewModel(person)); 
// IEnumerable is just provided with a query. No other operation is done 

AllPeople = new ObservableCollection<PersonViewModel>(allPeople); 
// The ObservableCollection requests element from allPeople 
// which in turn requests from the query 
// which in turn requests from _people 
// which enumerates the result of GetAll() and yields the result. 

Par conséquent, vous pouvez éviter la création de listes temporaires.

En outre, même la méthode GetAll() pourrait être faite pour retourner un IEnumerable si ce n'est pas le cas.

Vous pouvez jeter un oeil à
IEnumerable
IQueryable
yield

+0

Merci pour la suggestion de faire la liste dans IEnumerable Collection. Ma principale préoccupation vient ici IEnumerable allPeople = (de personne dans _people select new PersonViewModel (person)); comme j'ai beaucoup de méthodes appelant à définir des propriétés sur le PersonViewModel.It prend beaucoup de temps pour que chaque enregistrement passe par toutes les méthodes. Mais maintenant, après l'avoir mis à IEnumerable, il ne prend pas beaucoup de temps mais lorsque le point de débogage passe à AllPeople = new ObservableCollection (allPeople); ligne il faut un certain temps pour charger – crazy9

+0

@ user311945: À un moment donné de toute façon la liste solide doit être créé et donc l'heure. Mais cela ne devrait pas prendre beaucoup de temps comme vous le spécifiez. Devrait être moins d'une seconde pour des milliers d'articles. Pouvez-vous poster le code pour le constructeur PersonViewModel et d'autres choses que vous consommez du temps. Utilisez la classe Stopwatch. – Amsakanna