Reputation: 748
I'm using MVVM for a WPF client that represents a model and allows users to interact with it. I've always shied away from using the ObservableCollection class in the actual model (opting for generic collections like IList inside that model instead, and then converting that IList to the actual data-bound ObservableCollection on the ViewModel when the underlying collection changes). Reason being that MSDN presents the class as WPF and UI-centric:
You can enumerate over any collection that implements the IEnumerable interface. However, to set up dynamic bindings so that insertions or deletions in the collection update the UI automatically, the collection must implement the INotifyCollectionChanged interface. This interface exposes the CollectionChanged event, an event that should be raised whenever the underlying collection changes. WPF provides the ObservableCollection class, which is a built-in implementation of a data collection that implements the INotifyCollectionChanged interface.
Question: Is my distinction actually necessary? It's extra work and extra code. I understand that this topic might be too vague and subjective for SO, but maybe there are clear, universally agreed-upon conventions everybody follows.
Upvotes: 3
Views: 3945
Reputation: 169160
Is my distinction actually necessary?
It depends on what a model really is in this case, or rather how you define a model.
If it is some kind of domain business object that is defined in an assembly that is referenced by your business or service layer and may be used across your entire domain, it shouldn't implement any kind of client-specific interfaces such as INotifyCollectionChanged
.
Then you should prefer to use a generic type such as IList
and then create a wrapper class in the client application that you bind to the view element to.
But if the model is a class that is used only inside your client application and not in any other tiers of your application, then you might as well define the collection property as an ObservableCollection
and bind to this one directly.
The point is that a domain business object should not have any knowledge of WPF or the fact that a client application may bind to it. That's why it seldom makes sense to bind directly to such objects in a WPF application without wrapping them in WPF-aware view model classes first.
This does add some extra work and an additional class but at the same time it helps maintain separation of concerns which is usually good for maintenance.
In an enterprise scenario it is also pretty common that the business object may contain business logic that you don't want to expose to the client and it also may contain additional properties that it makes no sense to expose to the view. So then you still need to wrap it in another class even if the collection property should actually return an ObservableCollection
.
So if your question is "should I use ObservableCollections in the business objects" the answer is no.
Upvotes: 3
Reputation:
Yes I think you are doing it right. Observable collections belong at the presentation layer. Add them to your view model, not your domain model.
This question may be of some help
but maybe there are clear, universally agreed-upon conventions everybody follows.
Please let me know when you find them, thx.
Upvotes: 5