9
votes

Puis-je modifier la collection Rollback sur la collecte modifiée?

J'ai 2 vues de liste ... et ajouter / supprimer des boutons entre eux.

On Collection Modification d'un événement d'une liste de visualisation dans ViewModel, puis-je annuler les modifications pour une condition particulière?


0 commentaires

3 Réponses :


1
votes

Vous envisagez d'obtenir l'expéditeur de l'événement en tant qu'objet (c.-à-d. Le premier paramètre de l'événement) et la liste des objets modifiés, oui, vous pouvez le faire. Je ne conseillerais pas ça. Si vous rencontrez une telle condition, fournissez une méthode sur la vue de la vue fournie avec le evenargs et que cela fait le travail. La vue n'est pas l'endroit où faire la logique.

Mieux encore mieux: Vérifiez la condition dans la vue de la vue elle-même (c'est-à-dire dans les commandes qui sont responsables pour ajouter / supprimer)! Le point de vue est responsable de l'état de l'information, alors gardez votre logique là-bas. La vue est juste là pour afficher les données.


1 commentaires

Une question => Si j'ignore E.Olditems à ma collection, n'allume-t-il pas à nouveau une collection modifiée?



5
votes

Vous pouvez gérer le collectionchangned code> Evénement du Observablecollection code> à la sauvegarde (via la machine virtuelle ou autre) les anciennes valeurs (voir notifycollectionChangeDeventargs.olditems code> propriété) et récupérez-les en cas de besoin lorsque l'utilisateur clique sur" annuler "etc.

Mise à jour forte> en référence aux commentaires ci-dessous: p>

Si vous souhaitez annuler la collecte de la collection de la collection CODE> CollectionChanged code> Event-Handler, créez un drapeau où vous échappez au gestionnaire À partir d'un appel récursif (non testé avec une application multi-threadée), voici un exemple simple, vous pouvez facilement le modifier pour s'adapter à votre V / VM. P>

private void Window_Loaded(object sender, RoutedEventArgs e)
{
  var x = new ObservableCollection<string>();
  x.CollectionChanged += 
    new NotifyCollectionChangedEventHandler(x_CollectionChanged);
  x.Add("asdf");
  x.Remove("asdf");
}

bool rollingBack = false;
void x_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
  if (rollingBack) return;

  if (e.Action == NotifyCollectionChangedAction.Remove)
  {
    if (e.OldItems.Contains("asdf"))
    {
      var oc = (ObservableCollection<string>)sender;
      rollingBack = true;
      oc.Add("asdf");
      rollingBack = false;
    }
  }
}


12 commentaires

Une question => Si j'ignore E.Olditems à ma collection, n'allume-t-il pas à nouveau une collection modifiée?


Vous ne pouvez pas attribuer à E.Alditems, c'est 1) une propriété loadonly, 2) il renvoie un loadonlist .


Je veux dire ... ma collection observable = E.Alditems..Can je change de lecture à une collection observable?


Non, mais vous pouvez simplement lire / remplacer les anciens éléments dans votre collection observable, n'oubliez pas que l'argument expéditeur transmet au gestionnaire collection est le Observablecollection lui-même.


Par exemple, var x = (Observablecollection ) expéditeur; (votre Observablecollection et son type), puis foreach (Var Article dans E.Alditems) x. Ajouter (article);


Donc, cela ne posera pas à nouveau un événement de collectionChanged, n'est-ce pas?


Ce sera, bien sûr, et cela mettra à jour votre interface utilisateur, mais vous n'êtes pas destiné à effectuer la restauration de l'intérieur du gestionnaire de collection de toute façon, ce gestionnaire doit être utilisé pour récupérer et sauvegarder les données modifiées afin de la modifier. Lorsque l'utilisateur cliquez sur Annuler, vous l'avez juste là. Si vous souhaitez que la restauration du gestionnaire, créez simplement un drapeau que le gestionnaire devrait s'échapper quand il en est un, affichez ma réponse mise à jour.


Comment avez-vous obtenu cela pour travailler? Lorsque j'essaie de faire cela, j'obtiens une invalidopérationException "Impossible de modifier Observablecollection lors d'un événement de collection." - J'essaie d'autoriser un utilisateur à annuler de supprimer une ligne dans un DataGrid.


@Tod peut-on le déboguer et voir où est exactement la source de votre exception?


Droit sur le .add où j'essaie de remettre l'article dans la collection.


@Tod, ça fait longtemps que j'ai traité cette question, je ne peux pas sembler souvenir de ce qui se passe. J'espère que l'une des personnes ci-dessus pourrait être capable d'aider. Désolé ce n'est pas moi :(


Merci quand même, j'ai décidé de prendre une approche différente de cela.



0
votes

La réponse de Shimmy n'a pas fonctionné pour moi sur une application Windows Store, vous rencontrerez toujours des problèmes de ré-entrancy et obtenez un InvalidOperationException Dire "Impossible de modifier Observablecollection lors d'un événement de collection." p> Je devais utiliser le répartiteur de l'interface utilisateur et désactiver / activer le gestionnaire d'événements d'éviter ces problèmes.

être averti: Ceci est un piratage, et les concepteurs-cadres ont fait de grandes longueurs pour vous empêcher de faire des actes. . Donc, si vous voulez ignorer leur avertissement, soyez prudent de ne pas vous tirer au pied. xxx

Cela évitera l'exception, évitez d'appeler le gestionnaire de récursivité et mettez à jour l'interface utilisateur. correctement.


1 commentaires

Et la réponse acceptée ne fonctionne pas dans une application de bureau WPF non plus. Regardez mon POST aussi.