Advice on where and when to use ObservableCollection in MvvmCross

In the MvvmCross solution, I have a single-level service class that gets items from a web service and updates the public ObservableCollection. He does this every five seconds, and elements can be added or removed or their properties changed.

I also have a ViewModel that has a public property that is set in the Service ObservableCollection. The view is associated with an ObservableCollection, so when elements are added, deleted, or changed, the view must be updated to show this.

However, as expected, I get an exception for streaming because the ObservableCollection is updated by a thread other than Main / UI, and therefore the binding cannot update the user interface.

Inside the service, I don't have an InvokeOnMainThread call available, so there is no obvious cross-platform way to get back to the main thread when updating the ObservableCollection. Also, doing it just seems wrong - the service should not relate to UI issues (while the ViewModel can).

Also, I'm a little nervous about showing events from the Service if this causes ViewModels to not be garbage collected. I note that at @slodge N + 1 series http://mvvmcross.wordpress.com/ he uses the messenging service, presumably to avoid this.

Thus, a possible solution could be to publish a message with the last list of elements, and for ViewModel to subscribe to the message and update its own ObservableCollection in the user interface stream by comparing the contents of the message with it. But that seems a little awkward.

Any suggestions on the best way to implement this will be appreciated - thanks.

+4
source share
1 answer

The initial requirement that INotifyCollectionChanged should be called in the user interface thread really comes from the synchronous way to update Windows updates based on notifications with Add / Remove / Move / Replace / Reset.

This synchronous update, of course, is perfectly reasonable - it would be very difficult to update the display of the user interface, while another thread is actively changing it.

There are β€œnew” changes in .Net 4.5 that may mean that the future will be more pleasant ... but overall they look rather difficult for me - see fooobar.com/questions/107401 / ...


The ways I know for this are basically the same as in your post:

a. keep the ObservableCollection at the Service / Model level and place there all the events in the user interface thread - this is possible using any class that inherits from MvxMainThreadDispatchingObject , or can be done by calling MvxMainThreadDispatcher.Instance.RequestMainThreadAction(action)

Although this is bad, it means that your service / model has some knowledge of streaming, this approach may work well for the overall experience with applications.

C. Duplicate the copy of the collection in the ViewModel - updating it using some weak reference type mechanism

  • eg. By sending them messages that tell him what was added, deleted, replaced or moved (or completely Reset) - note that this requires that the messages arrive in the correct order!

  • or, for example, allowing you to transfer pictures from the Service / Model level

Which one to choose depends on:

  • the frequency, type, and size of changes to the collection β€” for example, whether you receive periodic updates on a single line, whether you receive frequent large spurts of changes, or if you see mostly complex groups of changes (which are essentially Resets in relation to the user interface).
  • animation level required in the user interface. Should animate in / out elements be added / removed? If animation is not required, it can sometimes be easier to simply replace the entire list with a new snapshot rather than handle incremental changes.
  • the size of the collection itself - obviously duplicating a large collection can cause memory problems.
  • persistence required for the collection - if persistence is required, then the ObservableCollection itself may not be acceptable, and you may need to use a custom implementation of INotifyCollectionChanged (for example, MyCustomList samples )

Usually I usually choose approach (A) in applications, but it depends on the situation and on the characteristics of the collection and its changes.

Note that although this is definitely a mvvm problem, the main problem is not dependent on data binding - how do you update the screen display of a list while the list itself changes to a background thread?

+12
source

Source: https://habr.com/ru/post/1499139/


All Articles