Reputation: 34335
Is there a best practice way to bind an object's list property when it's not observable? For example, if we have:
public class Band
{
public string Name { get; set; }
public List<Musician> Members { get; private set; }
// other properties here
}
If my view model has a Band
property, and I want my UI to bind to the Members
property, how are updates to the Members
property shown on the UI? Members is not observable.
The current thought is to create a DTO that is an exact copy of the Band
class, but make Members
an ObservableCollection
. Then the UI would bind to this DTO. Before the view model closes, it would map the DTO back to the proper Band
class. This seems like a bit of overhead. Is there a better way?
Edit - Another Option
I just had a discussion, in person, with someone about this. The idea is to add an ObservableCollection
property on the view model. Then, in the constructor of the view model, use the entity to populate the ObservableCollection
. After the user is done editing, use the updated ObservableCollection
to reset the List
on the entity.
Upvotes: 4
Views: 831
Reputation: 17509
Your edit rather made the question more confusing. Answer why should be using ObservableCollection.
You should be using ObservableCollection when, well, you want your UI to observe this collection. I mean, when you expect to be modifying this collection (not talking about the item in this collection, but collection as a whole). If you expect to add/remove/sort/filter this collection... if none of these operations is expected, then you are good to bind to IEnumerable also!
Also note, the properties in the underlying item are modified are not has nothing to do with how you are binding the collection as (IEnumerable or Observable). The updates in properties of underlying item are reflected (or not) if the underlying type raises appropriate notification changed event (and implements INotifyPropertyChanged).
Hope that helps!
Upvotes: 0
Reputation: 9089
As you mentioned, you could use ObservableCollection
. You could also use a BindingList
.
If you do not want to go that route, another other option I see is to make Band
implement INotifyPropertyChanged
and then invoke PropertyChanged
with your Members
property name
. That will tell the consuming controls that the list was updated and refresh itself.
The issue going with that route is it may be more of pain to try and figure when to invoke the PropertyChanged
event than just changing your collection to be ObservableCollection<T>
or BindingList<T>
.
Last option is to rebind the collection every time you think it changed or if the control supports it, call the an available Refresh
method. Something somewhere has to tell the control that the collection changed because they do not periodically check.
Because you tagged this as MVVM, your View should have a BandViewModel
and an ObservableCollection of MemberViewModel
s. Everything in a ViewModel is supposed to be bindable and send out notifications when something changed.
Upvotes: 2