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.
Related
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.
Using MVVM in a Silverlight project, I would like to be able to take advantage of the INotifyPropertyChanged interface by using ObservableCollections as the source of the data for a Master/Detail configuration. For the source of the Master list, I would like to use an ObservableCollection that retrieves a minimum number of fields from my database to minimixe loading time, and a different ObservableCollection for my Detail view that includes all fields for editing. Doing this with two different ObservableCollections seems to defeat the INotifyPropertyChanged advantage of using ObservableCollection since the changes are being made to a different ObservableCollection than the one used for the Master List. Is there a way to minimize data loading time for the list and still take advantage of INotifyPropertyChanged?
ObservableCollections notify upon changes in the collection - as in add/remove. They do not handle properties within the objects. The objects themselves have to implement INotifyPropertyChanged.
Objects added to the collections are added by reference. That means that if you update the object...it is updated. It won't make any difference which/how many lists contain the object.
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.
I have asked this question on MSDN forums as well ...
http://social.msdn.microsoft.com/Forums/en/wpf/thread/4493988a-9bd8-48fe-aff0-348502136a80
I need to know that why Microsoft suggests that BindingList is not properly supported in WPF...
What is it that doesnt work with BindingList in WPF? I find it pretty useful as it is. So far I personally have not found BindingList any slower or a having more load on memory.
Plus WPF ItemsControls, ItemsTemplates, Styles, Hierarchies work great with BindingLists too. They are equally observable.
Being a hardcore WPF developer myself and an ObservableCollection fan, my faith is getting shaken by a been-there-done-that BindingList....
Why should I use ObservableCollection over BindingList?
(keeping aside INotifyPropertyChanged which both have to implement for item property changes)
This may be of interest:
http://www.themissingdocs.net/wordpress/?p=465
most important paragraphs:
But the implementation does not scale, it is slow, it performs terribly with larger lists. If your element type supports INotifyPropertyChanged, every time one of those elements raises the property changed event the entire list is walked to work out the index in the list of the item which raised the event! I was in shock when I first realised this. You see BindingList is truly just a rather thin wrapper over Collection, so there is no metadata associated with each entry, all of the binding of the element PropertyChanged event is directed to a single handler, and all it gets given is the source and the name of the changed property, so there is no way to include the NewIndex parameter in ListChangedEventArgs without doing a search. (By default this search even uses the default object comparator, so if you happen to have two different but sometimes equal objects in your list, enjoy the results…)
Another side note – AddNew, the other feature which BindingList has which Collection does not – also does not scale. It has to use IndexOf to find out where in the list the newly added item ended up in case it needs to cancel the add, because it supports auto sorting in derived types. (BindingList does not support auto sorting itself…)
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.