Comment mettre à jour un seul élément dans une classe ObservableCollection?
Je sais comment faire un ajout. Et je sais comment rechercher l'ObservableCollection un élément à la fois dans une boucle "pour" (en utilisant Count comme représentation de la quantité d'éléments) mais comment puis-je modifier un élément existant. Si je fais un "foreach" et trouve quel élément doit être mis à jour, comment le remettre dans la ObservableCollection>
Vous n'avez pas besoin de supprimer un élément, de le modifier, puis de l'ajouter. Vous pouvez simplement utiliser la méthode LINQ FirstOrDefault
pour trouver l'élément nécessaire en utilisant le prédicat approprié et modifier ses propriétés, par exemple:
var item = list.FirstOrDefault(i => i.Name == "John");
if (item != null)
{
item.LastName = "Smith";
}
La suppression ou l'ajout d'un élément à ObservableCollection
générera un événement CollectionChanged
.
Vous ne pouvez généralement pas modifier une collection que vous parcourez (avec foreach
). Le moyen de contourner cela est de ne pas le répéter lorsque vous le changez, bien sûr. (x.Id == myId
et LINQ FirstOrDefault
sont des espaces réservés pour vos critères/recherche, l'important est que vous ayez l'objet et/ou l'index de l'objet)
for (int i = 0; i < theCollection.Count; i++) {
if (theCollection[i].Id == myId)
theCollection[i] = newObject;
}
Ou
var found = theCollection.FirstOrDefault(x=>x.Id == myId);
int i = theCollection.IndexOf(found);
theCollection[i] = newObject;
Ou
var found = theCollection.FirstOrDefault(x=>x.Id == myId);
theCollection.Remove(found);
theCollection.Add(newObject);
Ou
var found = theCollection.FirstOrDefault(x=>x.Id == myId);
found.SomeProperty = newValue;
Si le dernier exemple réussit, et ce que vous devez vraiment savoir, c'est comment faire en sorte que votre ObservableCollection
soit conscient du changement, vous devez implémenter INotifyPropertyChanged
sur la classe de l'objet et être sûr de augmenter PropertyChanged
lorsque la propriété que vous modifiez change (idéalement, elle devrait être implémentée sur toutes les propriétés publiques si vous avez l'interface, mais fonctionnellement bien sûr, cela n'a vraiment d'importance que pour celles que vous allez mettre à jour).
Voici exemples de Tim S comme méthodes d'extension au-dessus de la classe Collection:
FirstOrDefault
public static void ReplaceItem<T>(this Collection<T> col, Func<T, bool> match, T newItem)
{
var oldItem = col.FirstOrDefault(i => match(i));
var oldIndex = col.IndexOf(oldItem);
col[oldIndex] = newItem;
}
public static void ReplaceItem<T>(this Collection<T> col, Func<T, bool> match, T newItem)
{
for (int i = 0; i <= col.Count - 1; i++)
{
if (match(col[i]))
{
col[i] = newItem;
break;
}
}
}
Imaginez que vous ayez cette configuration de classe
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
Vous pouvez appeler l'une des fonctions/implémentations suivantes, comme celle-ci, où le paramètre match
est utilisé pour identifier l'élément que vous souhaitez remplacer:
var people = new Collection<Person>
{
new Person() { Id = 1, Name = "Kyle"},
new Person() { Id = 2, Name = "Mit"}
};
people.ReplaceItem(x => x.Id == 2, new Person() { Id = 3, Name = "New Person" });
<Extension()>
Public Sub ReplaceItem(Of T)(col As Collection(Of T), match As Func(Of T, Boolean), newItem As T)
For i = 0 To col.Count - 1
If match(col(i)) Then
col(i) = newItem
Exit For
End If
Next
End Sub
FirstOrDefault
<Extension()>
Public Sub ReplaceItem(Of T)(col As Collection(Of T), match As Func(Of T, Boolean), newItem As T)
Dim oldItem = col.FirstOrDefault(Function(i) match(i))
Dim oldIndex = col.IndexOf(oldItem)
col(oldIndex) = newItem
End Sub
Cela dépend de quel type d'objet il s'agit.
S'il s'agit d'une classe C # ordinaire, modifiez simplement les propriétés de l'objet. Vous n'avez rien à faire à la collection. La collection contient une référence à l'objet qui est la même même si les propriétés de l'objet changent. Un changement sur l'objet ne déclenchera pas la notification de changement pour la collection elle-même, car la collection n'a pas vraiment changé, juste un des objets qu'elle contient.
S'il s'agit d'une classe C # immuable (telle qu'une chaîne), un struct
ou un autre type de valeur, vous devez supprimer l'ancienne valeur et ajouter la nouvelle.