There is a user model in which there is a list of messages of this user.

class User { public int Id {get; set;} public List<string> Messages {get;set;} } 

In the interface, we can view, edit and delete these messages.

Now in UsersVM I added ObservableCollection<string> Messages and when the edit or delete command is triggered, I UsersVM.Messages these changes both to the UsersVM.Messages and User.Messages models, which is not very correct, as it seems to me.

Tell me how to do it right?

  • And why it seems to you that this is not very correct? - VladD
  • @VladD, the fact that the model implements INotifyCollectionChanged , I suppose - user227049
  • @FoggyFinder: Okay, what's so bad about that? The model has the right to do as she pleases, then she and the model. - VladD
  • @VladD violates the classic MVVM , but I don’t see anything wrong with not following all the requirements. - user227049
  • one
    @maxwell: I see no problems with this. Look, for example, here: ru.stackoverflow.com/a/379331/10105 - VladD

1 answer 1

Of course, duplicate data is not rational. Implement the INotifyCollectionChanged interface


In fact, this may not be so easy, but, benefit, there is access to the source codes ObservableCollection

As you can see, the basis of this class is Collection<T> :

The Collection class also has a constructor that accepts an existing IList implementation. Unlike other classes of collections, the transferred list is not copied, but a proxy is created for it, which means that subsequent changes will be reflected in the Collection shell (although without launching the virtual Collection methods). Conversely, changes made through the Collection will affect the underlying list.

Thus, we can copy the ObservableCollection implementation and add to it something like this constructor (replace the existing one (-e)):

 public ObservableCollection(IList<T> list) : base(list) { } 

This will allow you to use a ready-made collection of the model, without duplication and, at the same time, all the advantages of the ObservableCollection

  • four
    Can you give an example for this case, as in the answer? Make your answer more informative. - Vadim Ovchinnikov
  • @VadimOvchinnikov, updated the answer. - Andrey NOP
  • one
    Great, but tell me, is it not easier to inherit from ObservableCollection than to carry with you an almost complete double of its source code? - Vadim Ovchinnikov
  • @VadimOvchinnikov, unfortunately your option will not work, because Collection.Items does not have a setter and the only option is to assign a link to your IList to the private field of items : a call to the Collection(IList<T> list) constructor Collection(IList<T> list) . In the child ObservableCollection functionality is redefined and it uses copying from one list to another, and not copying the link to the list. - Andrei NOP
  • You can inherit and add a private setter for Collection.Items , where reflection will be used to set values ​​for the items private field. - Vadim Ovchinnikov