Manipulating ObservableCollection vs Replacing a List - wpf

I have a backend Dictionary that is used for synchronization (ie. to both a filestore and a webservice).
Off the top of this I need to generate lists/enumerables for the WPF frontend to consume. What is the difference between either hooking an enumerable up to the dictionary, and calling PropertyChanged when it is updated to using an ObservableCollection and having it automatically called its CollectionChanged.
Synchronizing occurs in the background automatically, and some elements may be removed, others may be updated. I want to propagate this information to the WPF frontend and user smoothly. (ie. if one item is removed, the whole display shouldn't have to be reinitialized). I also want to add animation when items are added and removed (ie. fade in and out) - is this possible if I replace the whole list or will it cause every single item to fade in again?
So should I:
1) use an observable collection and write some fancy synchronization logic between the dictionary and the collection?
2) use linq extension methods to convert the dictionary to an enumerable and simply call propertychanged on the enumerable whenever it changes?
3) synchronize between a dictionary and a list, by replacing the list whenever it is updated?
Also, how would any of these work with sorting and filtering operations that are performed just for the UI? (ie. if I need to filter some elements out of the dictionary based upon user selection, should I use a similar method as the one you have recommended?)

If you "replace" any IEnumerable<T> when you get a change, the entire list will be refreshed in the UI.
In order to avoid that, you'll need to implement INotifyCollectionChanged, and provide a collection which implements this. Instead of replacing the collection, you handle the elements, which in turn fires the appropriate events.
ObservableCollection<T> handles this for you. Personally, if you need to keep this in a dictionary, but want to synchronize it to a list, you may want to consider making a custom collection, possibly based around SortedDictionary. A standard Dictionary has no sense of ordering, which means that there'd be no way to implement INotifyCollectionChanged appropriately.

Related

WPF bind property to array value using Prism MVVM [duplicate]

I have lots of entities with nested List<> in each.
For example, I have BaseEntity which has List<ColumnEntity>.
ColumnEntity class has List<Info> and so on.
We are working with a WPF UI, and we need to track all changes in every List of BaseEntity. It is implemented by instantiating a new ObservableCollection based on the needed list, and with binding to that ObservableCollection.
What are the pros and cons changing all these nested Lists to ObservableCollections? So we can track all changes in BaseEntity itself without reassigning each list of BaseEntity to modified bound ObservableCollection?
Assuming that methods specific to List are never used.
Interesting question, considering that both List and ObservableCollection implement IList<T> there isn't much of a difference there, ObservableCollection also implements INotifyCollectionChanged interface, which allows WPF to bind to it.
One of the main differences is that ObservableCollection does not have AddRange method, which might have some implications.
Also, I would not use ObservableCollection for places where I know I would not be binding to, for this reason, it is important to go over your design and make sure that you are taking the correct approach in separating layers of concern.
As far as the differences between Collection<T> and List<T> you can have a look here
Generic Lists vs Collection
It depends on exactly what you mean by this:
we need to track all changes in every List of BaseEntity
Would it be enough to track changes to objects already in the list? Or do you need to know when objects are removed from/are added to/change positions within the list?
If a list will contain the same items for their whole lifetime, but the individual objects within that list will change, then it's enough for just the objects to raise change notifications (typically through INotifyPropertyChanged) and List<T> is sufficient. But if the list will contain different objects from time to time, or if the order changes, then you should use ObservableCollection<T>.
So while the differences may be interesting (and a previous poster has already covered those), typically you won't have that much of a choice - either you need ObservableCollection<T> or you don't.
List represents a strongly typed list of objects that can be accessed by index. It provides methods to search, sort, and manipulate lists. The List class is the generic equivalent of the ArrayList class. It implements the IList generic interface using an array whose size is dynamically increased as required.
ObservableCollection is a generic dynamic data collection that uses an interface "INotifyCollectionChanged" to provide notifications when items get added, removed, or when the whole collection is refreshed.
Read more about it in this link: http://www.codeproject.com/Articles/42536/List-vs-ObservableCollection-vs-INotifyPropertyCha
One more important difference is you can access ObservableCollection only from thread on which it was created where as list can be accessed fromany thread.
I see no problem with that, other than a very marginal performance overhead.
Note that if you modify the internal Lists directly, you are not notified about changes. Also if the objects which are contained in the ObservableCollection are modified you are not notified. Notification occurs only, if elements are added, replaced, removed or moved.

Bool to Visibility Converter using a bool List [duplicate]

I have lots of entities with nested List<> in each.
For example, I have BaseEntity which has List<ColumnEntity>.
ColumnEntity class has List<Info> and so on.
We are working with a WPF UI, and we need to track all changes in every List of BaseEntity. It is implemented by instantiating a new ObservableCollection based on the needed list, and with binding to that ObservableCollection.
What are the pros and cons changing all these nested Lists to ObservableCollections? So we can track all changes in BaseEntity itself without reassigning each list of BaseEntity to modified bound ObservableCollection?
Assuming that methods specific to List are never used.
Interesting question, considering that both List and ObservableCollection implement IList<T> there isn't much of a difference there, ObservableCollection also implements INotifyCollectionChanged interface, which allows WPF to bind to it.
One of the main differences is that ObservableCollection does not have AddRange method, which might have some implications.
Also, I would not use ObservableCollection for places where I know I would not be binding to, for this reason, it is important to go over your design and make sure that you are taking the correct approach in separating layers of concern.
As far as the differences between Collection<T> and List<T> you can have a look here
Generic Lists vs Collection
It depends on exactly what you mean by this:
we need to track all changes in every List of BaseEntity
Would it be enough to track changes to objects already in the list? Or do you need to know when objects are removed from/are added to/change positions within the list?
If a list will contain the same items for their whole lifetime, but the individual objects within that list will change, then it's enough for just the objects to raise change notifications (typically through INotifyPropertyChanged) and List<T> is sufficient. But if the list will contain different objects from time to time, or if the order changes, then you should use ObservableCollection<T>.
So while the differences may be interesting (and a previous poster has already covered those), typically you won't have that much of a choice - either you need ObservableCollection<T> or you don't.
List represents a strongly typed list of objects that can be accessed by index. It provides methods to search, sort, and manipulate lists. The List class is the generic equivalent of the ArrayList class. It implements the IList generic interface using an array whose size is dynamically increased as required.
ObservableCollection is a generic dynamic data collection that uses an interface "INotifyCollectionChanged" to provide notifications when items get added, removed, or when the whole collection is refreshed.
Read more about it in this link: http://www.codeproject.com/Articles/42536/List-vs-ObservableCollection-vs-INotifyPropertyCha
One more important difference is you can access ObservableCollection only from thread on which it was created where as list can be accessed fromany thread.
I see no problem with that, other than a very marginal performance overhead.
Note that if you modify the internal Lists directly, you are not notified about changes. Also if the objects which are contained in the ObservableCollection are modified you are not notified. Notification occurs only, if elements are added, replaced, removed or moved.

Best collection to use for speed in WPF GUI

I have a listview that contains a list of 'rows', which in term, contains a list of 'columns'. For now, I use List for both rows and columns (i.e. I have a List and it the Rows objet, I have a List, but as the number gets bigger, the time it takes to update the GUI and overall performance of the program gets pretty bad. Plus, the GUI isn't notified when the items (columns within the rows) change, so I have to do an Item.Refresh, which seems to refresh the whole thing each time, adding to the slow performance
Is there any other type of object that I could use to accelerate the whole thing. Meaning it would need to satisfied the following points :
- Faster that List
- When I add a new rows, the listview is updated. Is possible, only the new rows is added instead of the whole listview.
- When I change a Columns object, the GUI is updated. If possible, only the modified columns objet is affected so the whole Listview is not changed.
Note that there are quite a number of actual calculations behind the scene for displaying the columns object. I have currently working on optimizing this end, but I'm pretty sure using a better collection would help quite a lot here.
Thanks
I believe what you are looking for is an Observable Collection
This collection type will fire a CollectionChanged event when items are added. You will not need to refresh the collection because WPF controls support this out of the box.
Note
The CollectionChanged event will not be fired when indiviual elements are updated. If you want these updates to show on the UI, the object within the collection should implement INotifyPropertyChanged

WPF: How to create a collection that can be bound to

My app has a background thread that periodically retrieves data from an external source, in the form of key/value pairs. I would like to expose this data for binding, presumably by storing them in some kind of static(?) model, as the data will be needed by numerous views throughout my app. There are potentially hundreds of these keys, and may be different for each customer, so I can't simply create an INotifyPropertyChanged model with a property for each value.
The app has multiple views visible at any one time, and each of these will have numerous controls (usually textboxes) that I want to bind to individual items in the above collection. When a value in the collection is updated, any controls bound to only that item should change to reflect the new value. I'm assuming an ObservableCollection wouldn't be suitable here, as a change to a single item will result in all controls updating, regardless of which item they are bound to?
To throw a further complexity into the mix, some values (which are numeric) will need formatting for display, e.g. number of decimal places, or adding a suffix such as "volts". The formatting rules are user-defined so I can't hardcode them into (say) the XAML binding's StringFormat expression. Ideally I should be able to access both the raw value (e.g. for calculations), and the formatted version (for display purposes). I'm sure it must be possible to achieve the latter using some clever WPF feature!
I would appreciate any pointers on how I can solve these requirements.
Edit: it's worth mentioning that I've previously tried implementing the model as some kind of collection. The problem is that it won't be initially populated with all values, and these only get added some time later. When they do eventually get added, a bound control doesn't update - presumably because it wasn't initially able to bind to the missing value.
I would take a different approach, namely a variation of Event Aggregation. I would have a single class that manages the overall collection (probably a singleton class like franssu suggested), but instead of binding directly to the collection in that class you create smaller models that are more specific to the individual views.
When your main model receives a new item, it publishes an event, which is consumed by the smaller models who can inspect the new item and determine whether or not they should add that item to their internal collection (the one the individual views are bound to). If it doesn't "belong" to their view, they can simply ignore the event.
You could use similar event publishing for updates to items and such, although if you're binding to the actual items you probably don't need that.
Just implement the INotifyCollectionChanged Interface and the INotifyPropertyChanged and you ll get a Collection like the ObservableCollection.
But rember if you select a Item from your Collection (as example a ObservableCollection) and you change that item your other controls won t update. So if you have a class Person in your Collection and you change the name of one person the other controls won t get the new name of the person.
Inside the Person object you still have to implement the INotifyPropertyChanged Interface and raise the event when your name changes.
So what I want to tell you is: A Collection with the interface INotifyCollectionChanged will only tell the bound controls: There is a new Item, there has been a item removed or a items index changed BUT not if the item itself changes.
So you ll need a Collection that provides the points above and a Item contained by the collection that raises events if a property of it changes.
ObservableCollection is perfect here. You should find that a standard ItemsControl bound to an ObservableCollection will only update the controls of the items that have changed, not every item in the collection.
This is the reason ObservableCollection exists - the events that it raises specifically identify items that have changed, so that the UI can handle them sensibly.
I've tested this locally with a small WPF app and it works fine. Worth noting, though, that a virtualised items panel would probbaly appear to break this behaviour when it scrolls...
EDIT: rereading your question, you actually say "When a value in the collection is updated..." If your collection contains instances of a class, and you update properties on the class, you don't even need ObservableCollection for this to work - you just need the class to implement INotifyPropertyChanged.

Returning Data from an Asynchronous Command in a WPF MVVM Application

I’m having a bit of difficulty getting this to work – and to be honest, I feel I may not be even doing this with the right approach.
In my View I have a Button and two list boxes.
What I want is to click the button and have the two list boxes populate with two separate lists of strings in an Asynchronous fashion.
In my ViewModel, I have two ObservableCollection properties and these are what the ListBox.ItemsSource properties are bound too. All good.
Now, I have an instance of AsyncDelegateCommand (outlined in this post - http://www.amazedsaint.com/2010/10/asynchronous-delegate-command-for-your.html#) which I have data bound to the Command property of the button.
In the DoSomething() method, I have just made a quick sample that constructs a list of random strings with a few sleep in-between to simulate some elapsed time.
How can I return this collection for use in the ViewModel? and then to take it a step further, How can I return multiple instances of this collection for multiple ListBoxes?
I hope this makes sense!
Kris
Using the AsyncDelegateCommand you referenced, you would subscribe to the Command's Completed event, and add the results of your collection from event args Result to your ObservableCollection.
This will automatically happen in the correct synchronization context (since that command uses BackgroundWorker to function), which will allow your UI to update appropriately.

Resources