There are lots of great examples around on MVVM but I'm still confused. Lets say you have a CustomerModel and a CustomerViewModel. It seems there would be a Name property on the CustomerModel and one on the CustomerViewModel. The setter on the CustomerViewModel
will set the CustomerModel Name property and then call the OnPropertyChanged(PropName) so that the UI will update. Is this really right? Seems like the getter/setters will be defined twice. If you have a model with 50 properties then thats going to get real
tedious. Also, lets say I set a Qty property. The ViewModel updates the Model. The Model updates its Value property based on the new Qty. How does the ViewModel get notified that the Model property changed?
You're absolutely right : Duplication of getters / setters when there is no validation logic at the ViewModel scope but straight property routing seems totally mad.
What I usually do is to expose a "Model" property that exposes the whole entity. Then in Xaml I Bind to Model.Property instead of Property
Simon Ferquel
MVP Client App Dev
http://www.simonferquel.net/blog
And thats the approach I was thinking of taking but then you stillhave other properties on the ViewModel - CanSave, CanCancel, IsValid, etc that are not related to the model. And that's ok until you get to a header/detail type situation (which was a spearate
post). Because then you have the details being a model but maybe that list of model also has CanSave, CanCancel type properties on it. So how do they then get surfaced.
Exposing the Model in your ViewModel class doesn't mean that you will allways go trough the Model properties for Binding.
Imagine Category/Product MasterDetails scenario.
Your CategoryViewModel can have two properties :
Model (the underlaying category)
ProductsViewModels (which is an ObservableCollection wrapping the Products property of the category).
It is not the cleanest way (because UI still has access to Model.Products), but it's a good compromise between the "clean" and the "productive".
Another way to do would be to bind directly to Model.Products and to drive instanciation of the Product ViewModels by the View with something like this :
<DataTemplate> <!-- This is a Product DataTemplate -->
<Grid>
<Grid.Resources>
<ProductViewModel Model="{Binding}" x:Key="ViewModel" />
</Grid.Resources>
</Grid>
</DataTemplate>
What do you think ?
Simon Ferquel
MVP Client App Dev
http://www.simonferquel.net/blog
Yes that's the way I was looking at it as well (your first option).
But what I am still confused on is the ProductsViewModels. The name implies a collection of ViewModel, not a collection of Model. So this comes back to by header/detail question as to how to do that wrapping. Maybe should move this part of the conversation
over to that thread.
Actually there was further issue. If you expose a Model property on your ViewModel, then you would be data binding to "Model.Name", "Model.Address", etc.
Do you do OnPropertyChanged in your Model properties setter methods in order for the binding to work properly? If you do then if you do OnPropertyChanged("Name") and OnPropertyChanged("Address") then does this work correctly since the binding is to "Model.Name"
and "Model.Address". Some tests I did here showed it was only when I went OnPropertyChanged("Model") that the bindings worked correctly but that seemed a bit of a sledgehammer approach.
tkd99
Member
1 Points
15 Posts
MVVM ViewModel linking to Model
Mar 18, 2009 05:26 AM | LINK
simon.ferquel
Member
344 Points
94 Posts
Re: MVVM ViewModel linking to Model
Mar 18, 2009 09:37 AM | LINK
You're absolutely right : Duplication of getters / setters when there is no validation logic at the ViewModel scope but straight property routing seems totally mad.
What I usually do is to expose a "Model" property that exposes the whole entity. Then in Xaml I Bind to Model.Property instead of Property
MVP Client App Dev
http://www.simonferquel.net/blog
tkd99
Member
1 Points
15 Posts
Re: Re: MVVM ViewModel linking to Model
Mar 18, 2009 11:09 AM | LINK
And thats the approach I was thinking of taking but then you stillhave other properties on the ViewModel - CanSave, CanCancel, IsValid, etc that are not related to the model. And that's ok until you get to a header/detail type situation (which was a spearate post). Because then you have the details being a model but maybe that list of model also has CanSave, CanCancel type properties on it. So how do they then get surfaced.
simon.ferquel
Member
344 Points
94 Posts
Re: Re: Re: MVVM ViewModel linking to Model
Mar 18, 2009 11:26 AM | LINK
Exposing the Model in your ViewModel class doesn't mean that you will allways go trough the Model properties for Binding.
Imagine Category/Product MasterDetails scenario.
Your CategoryViewModel can have two properties :
It is not the cleanest way (because UI still has access to Model.Products), but it's a good compromise between the "clean" and the "productive".
Another way to do would be to bind directly to Model.Products and to drive instanciation of the Product ViewModels by the View with something like this :
<DataTemplate> <!-- This is a Product DataTemplate -->
<Grid>
<Grid.Resources>
<ProductViewModel Model="{Binding}" x:Key="ViewModel" />
</Grid.Resources>
</Grid>
</DataTemplate>
What do you think ?
MVP Client App Dev
http://www.simonferquel.net/blog
tkd99
Member
1 Points
15 Posts
Re: Re: Re: Re: MVVM ViewModel linking to Model
Mar 18, 2009 11:51 AM | LINK
Yes that's the way I was looking at it as well (your first option).
But what I am still confused on is the ProductsViewModels. The name implies a collection of ViewModel, not a collection of Model. So this comes back to by header/detail question as to how to do that wrapping. Maybe should move this part of the conversation over to that thread.
http://silverlight.net/forums/p/80571/189514.aspx#189514
tkd99
Member
1 Points
15 Posts
Re: Re: Re: Re: Re: MVVM ViewModel linking to Model
Mar 18, 2009 11:58 AM | LINK
Actually there was further issue. If you expose a Model property on your ViewModel, then you would be data binding to "Model.Name", "Model.Address", etc.
Do you do OnPropertyChanged in your Model properties setter methods in order for the binding to work properly? If you do then if you do OnPropertyChanged("Name") and OnPropertyChanged("Address") then does this work correctly since the binding is to "Model.Name" and "Model.Address". Some tests I did here showed it was only when I went OnPropertyChanged("Model") that the bindings worked correctly but that seemed a bit of a sledgehammer approach.