A ViewModel is basically a value converter on steroids. I takes "raw" data and converts it into something presentation-friendly, and vice-versa. If you ever find yourself binding an element's property to a ViewModel's property, and you're using a value converter, stop! Why not just create a property on the ViewModel that exposes the "formatted" data, and then drop the value converter altogether?
The only place I can see a use for value converters in an MVVM architecture is cross-element bindings. If I'm binding the Visibility of a panel to the IsChecked of a CheckBox, then I will need to use the BooleanToVisibilityConverter. But, perhaps even in that case I should take the "high road" and bind the IsChecked to a property on the ViewModel, and then have a SomePanelVisibility property on the VM, to which the Panel is bound.
This is how I see things too. Note that in Silverlight, you cannot bind to ElementName (yet) so the high road is the only road available ;)
From: wpf-disciples@googlegroups.com [mailto:wpf-disciples@googlegroups.com] On Behalf Of Josh Smith Sent: Monday, December 01, 2008 5:09 PM To: wpf-disciples@googlegroups.com Subject: [WPF Disciples] Thought: MVVM eliminates 99% of the need for ValueConverters
A ViewModel is basically a value converter on steroids. I takes "raw" data and converts it into something presentation-friendly, and vice-versa. If you ever find yourself binding an element's property to a ViewModel's property, and you're using a value converter, stop! Why not just create a property on the ViewModel that exposes the "formatted" data, and then drop the value converter altogether?
The only place I can see a use for value converters in an MVVM architecture is cross-element bindings. If I'm binding the Visibility of a panel to the IsChecked of a CheckBox, then I will need to use the BooleanToVisibilityConverter. But, perhaps even in that case I should take the "high road" and bind the IsChecked to a property on the ViewModel, and then have a SomePanelVisibility property on the VM, to which the Panel is bound.
Do you agree???
No virus found in this incoming message. Checked by AVG - http://www.avg.com Version: 8.0.176 / Virus Database: 270.9.12/1822 - Release Date: 12/1/2008 8:23 AM
The other exception is when you need to implement a ForceReReadConverter to force the WPF Data Binding engine to requery the property it just changed.
Example: The business object has built in rules that can alter the case of the inputted entry. When the business object alters the case of the inputted text, it does raise the PropertyChanged event, which WPF ignores. So... in order to get the data binding engine to reread the value from the business object, you have to have a converter in place, this will cause the data binding pipeline to reread the value. Works great. Wish we didn't have to do this, but we do.
Karl
________________________________
From: wpf-disciples@googlegroups.com on behalf of Josh Smith Sent: Mon 12/1/2008 8:08 AM To: wpf-disciples@googlegroups.com Subject: [WPF Disciples] Thought: MVVM eliminates 99% of the need for ValueConverters
A ViewModel is basically a value converter on steroids. I takes "raw" data and converts it into something presentation-friendly, and vice-versa. If you ever find yourself binding an element's property to a ViewModel's property, and you're using a value converter, stop! Why not just create a property on the ViewModel that exposes the "formatted" data, and then drop the value converter altogether?
The only place I can see a use for value converters in an MVVM architecture is cross-element bindings. If I'm binding the Visibility of a panel to the IsChecked of a CheckBox, then I will need to use the BooleanToVisibilityConverter. But, perhaps even in that case I should take the "high road" and bind the IsChecked to a property on the ViewModel, and then have a SomePanelVisibility property on the VM, to which the Panel is bound.
If I'm not mistaken, I believe we created these patterns so we'd stop mixing UI logic code with logic code :-) Is the VM going to become The Next CodeBehind?
To put it another way, I think it risks mixing concerns. If I'm browsing the VM following the process for downloading the file and communicating whether it's done, I'd rather not see the code adding "%" after each number or an IsCancelButtonEnabled property. I'd much rather a ProgressPercentage integer property and a HasCompleted boolean property, and let the view convert it. The VM manages state, the view manages how it's visualized.
I think of the "state" of my VM as the conceptual state, not the real state. It's kind of like the difference between the Logical tree and the Visual tree, but at a domain level.
On Tue, Dec 2, 2008 at 2:38 AM, Josh Smith <flappleja...@gmail.com> wrote: > A ViewModel is basically a value converter on steroids. I takes "raw" data > and converts it into something presentation-friendly, and vice-versa. If > you ever find yourself binding an element's property to a ViewModel's > property, and you're using a value converter, stop! Why not just create a > property on the ViewModel that exposes the "formatted" data, and then drop > the value converter altogether?
> The only place I can see a use for value converters in an MVVM architecture > is cross-element bindings. If I'm binding the Visibility of a panel to the > IsChecked of a CheckBox, then I will need to use the > BooleanToVisibilityConverter. But, perhaps even in that case I should take > the "high road" and bind the IsChecked to a property on the ViewModel, and > then have a SomePanelVisibility property on the VM, to which the Panel is > bound.
Yes... and no. I think that if you're reaching for a value converter, you do need to stop and think, because it's often simpler, cleaner and easier to maintain to just use a special property on the view model. However, there's reasons beyond the ones you've given to not go for a special property.
1. If the value you need is unique to presentation, you should consider still using a converter. Visibility is a classic example. If one of your reasons to be using MVPoo is to be able to use multiple presentation frameworks (WPF, WinForms, WebForms, ASP.NET MVC, etc.) then the last thing you want to do is expose a property of type Visibility. Even if you're sticking to WPF, there's two possible "hidden" values with differing characteristics (hidden and collapsed). Choosing among these is a view concern, not a view model concern. (It actually bugs me that the BooleanToVisibilityConverter doesn't support this choice out of the box!)
2. Formatting is generally a presentation concern, and should be handled by the view. It may be tempting to add a property that formats that date in some specific way, but down the road when you use a different view that wants to format that date in another way, you have friction between views that may not be easily resolved. Again, if the conversion is to facilitate presentation, let the view handle it.
On Mon, Dec 1, 2008 at 11:08 AM, Josh Smith <flappleja...@gmail.com> wrote: > A ViewModel is basically a value converter on steroids. I takes "raw" data > and converts it into something presentation-friendly, and vice-versa. If > you ever find yourself binding an element's property to a ViewModel's > property, and you're using a value converter, stop! Why not just create a > property on the ViewModel that exposes the "formatted" data, and then drop > the value converter altogether?
> The only place I can see a use for value converters in an MVVM architecture > is cross-element bindings. If I'm binding the Visibility of a panel to the > IsChecked of a CheckBox, then I will need to use the > BooleanToVisibilityConverter. But, perhaps even in that case I should take > the "high road" and bind the IsChecked to a property on the ViewModel, and > then have a SomePanelVisibility property on the VM, to which the Panel is > bound.
> Do you agree???
-- Quidquid latine dictum sit, altum sonatur. - Whatever is said in Latin sounds profound.
War is peace. Freedom is slavery. Bugs are features.
On Mon, Dec 1, 2008 at 11:08 AM, Josh Smith <flappleja...@gmail.com> wrote: > A ViewModel is basically a value converter on steroids. I takes "raw" data > and converts it into something presentation-friendly, and vice-versa. If > you ever find yourself binding an element's property to a ViewModel's > property, and you're using a value converter, stop! Why not just create a > property on the ViewModel that exposes the "formatted" data, and then drop > the value converter altogether?
> The only place I can see a use for value converters in an MVVM architecture > is cross-element bindings. If I'm binding the Visibility of a panel to the > IsChecked of a CheckBox, then I will need to use the > BooleanToVisibilityConverter. But, perhaps even in that case I should take > the "high road" and bind the IsChecked to a property on the ViewModel, and > then have a SomePanelVisibility property on the VM, to which the Panel is > bound.
> Do you agree???
-- Quidquid latine dictum sit, altum sonatur. - Whatever is said in Latin sounds profound.
War is peace. Freedom is slavery. Bugs are features.
I see what you mean. I don't see my suggestion as promoting the ViewModel as the next code-behind, though. The code-behind of a View still serves a purpose in MVVM, aside from what the VM does. For example, I would never create a property in a code-behind and then bind an element's property to it. To me, the state of the UI includes the state of the functional areas in the UI, such as whether some panel is open or closed. In my way of thinking, that state belongs in the ViewModel.
On Mon, Dec 1, 2008 at 11:21 AM, Paul Stovell <stov...@gmail.com> wrote: > If I'm not mistaken, I believe we created these patterns so we'd stop > mixing UI logic code with logic code :-) Is the VM going to become The Next > CodeBehind?
> To put it another way, I think it risks mixing concerns. If I'm browsing > the VM following the process for downloading the file and communicating > whether it's done, I'd rather not see the code adding "%" after each number > or an IsCancelButtonEnabled property. I'd much rather a ProgressPercentage > integer property and a HasCompleted boolean property, and let the view > convert it. The VM manages state, the view manages how it's visualized.
> I think of the "state" of my VM as the conceptual state, not the real > state. It's kind of like the difference between the Logical tree and the > Visual tree, but at a domain level.
> On Tue, Dec 2, 2008 at 2:38 AM, Josh Smith <flappleja...@gmail.com> wrote:
>> A ViewModel is basically a value converter on steroids. I takes "raw" >> data and converts it into something presentation-friendly, and vice-versa. >> If you ever find yourself binding an element's property to a ViewModel's >> property, and you're using a value converter, stop! Why not just create a >> property on the ViewModel that exposes the "formatted" data, and then drop >> the value converter altogether?
>> The only place I can see a use for value converters in an MVVM >> architecture is cross-element bindings. If I'm binding the Visibility of a >> panel to the IsChecked of a CheckBox, then I will need to use the >> BooleanToVisibilityConverter. But, perhaps even in that case I should take >> the "high road" and bind the IsChecked to a property on the ViewModel, and >> then have a SomePanelVisibility property on the VM, to which the Panel is >> bound.
You're right about the multiple frameworks argument, but that's not my goal, so I didn't factor it into my thought. To be honest, I'd be very interested in seeing someone actually reuse a set of ViewModel classes in WinForms, ASP.NET, and WPF. I'd be happy enough just to see someone reuse them in WPF and SL. :)
Your point about "friction" between multiple Views raises a long-standing issue of mine. I think the terminology of MVVM is too limited. Really that pattern should be Model-ModelView-View-ViewModel (MMVVVM). The distiction between ModelView and ViewModel is the important point here. I've found that many times I create a VM for a model object, such as CustomerViewModel for Customer. I also create a ViewModel for a View object, such as CustomerViewModel for CustomerView. The friction you described is particular to the former case, where a "view model" is created for a model object, but not for one particular View. This is a sore point in the MVVM world.
I think that it is better to call a presentation-friendly wrapper around a Model object by its proper name: a ModelView. So, if I have a Customer class and want to make it easy to show an instance via binding in WPF, I should have a CustomerModelView class. If I have an input form that shows a new Customer, I should create an abstraction of that View, called CustomerViewModel. This way, the CustomerViewModel would perform the View-specific formatting, since it wouldn't be reused anywhere. However, the CustomerModelView could be shared across multiple Views and ViewModels.
On Mon, Dec 1, 2008 at 11:22 AM, Bill Kempf <weke...@gmail.com> wrote:
> Yes... and no. I think that if you're reaching for a value converter, > you do need to stop and think, because it's often simpler, cleaner and > easier to maintain to just use a special property on the view model. > However, there's reasons beyond the ones you've given to not go for a > special property.
> 1. If the value you need is unique to presentation, you should > consider still using a converter. Visibility is a classic example. > If one of your reasons to be using MVPoo is to be able to use multiple > presentation frameworks (WPF, WinForms, WebForms, ASP.NET MVC, etc.) > then the last thing you want to do is expose a property of type > Visibility. Even if you're sticking to WPF, there's two possible > "hidden" values with differing characteristics (hidden and collapsed). > Choosing among these is a view concern, not a view model concern. > (It actually bugs me that the BooleanToVisibilityConverter doesn't > support this choice out of the box!)
> 2. Formatting is generally a presentation concern, and should be > handled by the view. It may be tempting to add a property that > formats that date in some specific way, but down the road when you use > a different view that wants to format that date in another way, you > have friction between views that may not be easily resolved. Again, > if the conversion is to facilitate presentation, let the view handle > it.
> On Mon, Dec 1, 2008 at 11:08 AM, Josh Smith <flappleja...@gmail.com> > wrote: > > A ViewModel is basically a value converter on steroids. I takes "raw" > data > > and converts it into something presentation-friendly, and vice-versa. If > > you ever find yourself binding an element's property to a ViewModel's > > property, and you're using a value converter, stop! Why not just create > a > > property on the ViewModel that exposes the "formatted" data, and then > drop > > the value converter altogether?
> > The only place I can see a use for value converters in an MVVM > architecture > > is cross-element bindings. If I'm binding the Visibility of a panel to > the > > IsChecked of a CheckBox, then I will need to use the > > BooleanToVisibilityConverter. But, perhaps even in that case I should > take > > the "high road" and bind the IsChecked to a property on the ViewModel, > and > > then have a SomePanelVisibility property on the VM, to which the Panel is > > bound.
> > Do you agree???
> -- > Quidquid latine dictum sit, altum sonatur. > - Whatever is said in Latin sounds profound.
> War is peace. Freedom is slavery. Bugs are features.
> On Mon, Dec 1, 2008 at 11:08 AM, Josh Smith <flappleja...@gmail.com> > wrote: > > A ViewModel is basically a value converter on steroids. I takes "raw" > data > > and converts it into something presentation-friendly, and vice-versa. If > > you ever find yourself binding an element's property to a ViewModel's > > property, and you're using a value converter, stop! Why not just create > a > > property on the ViewModel that exposes the "formatted" data, and then > drop > > the value converter altogether?
> > The only place I can see a use for value converters in an MVVM > architecture > > is cross-element bindings. If I'm binding the Visibility of a panel to > the > > IsChecked of a CheckBox, then I will need to use the > > BooleanToVisibilityConverter. But, perhaps even in that case I should > take > > the "high road" and bind the IsChecked to a property on the ViewModel, > and > > then have a SomePanelVisibility property on the VM, to which the Panel is > > bound.
> > Do you agree???
> -- > Quidquid latine dictum sit, altum sonatur. > - Whatever is said in Latin sounds profound.
> War is peace. Freedom is slavery. Bugs are features.
>> For example, I would never create a property in a code-behind and then
bind an element's property to it.
So, I actually don't see a problem with that. Sometimes code-behind is a perfectly adequate view model. Especially if that property is very UI specific, such as whether a panel is collapsed.
I guess the way I think about it is the state of the UI is different to the state of the information making up the UI. A panel being open/closed is very UI-specific, in my books, so I probably wouldn't include it. If it was based on some information however - like whether a library book is overdue, then I might expose a property such as "IsOverdue" which my panel's visibility is based on. This comes down to how I want to seperate concerns - I want to know whether George remembered to check whether the book was on hold before making it available to borrow; not how he surfaced that in the UI.
I guess I see the VM as a way of shaping the domain model, rather than a way of completely simplifying the view.
On Tue, Dec 2, 2008 at 3:03 AM, Josh Smith <flappleja...@gmail.com> wrote: > Paul,
> I see what you mean. I don't see my suggestion as promoting the ViewModel > as the next code-behind, though. The code-behind of a View still serves a > purpose in MVVM, aside from what the VM does. For example, I would never > create a property in a code-behind and then bind an element's property to > it. To me, the state of the UI includes the state of the functional areas in > the UI, such as whether some panel is open or closed. In my way of > thinking, that state belongs in the ViewModel.
> Josh
> On Mon, Dec 1, 2008 at 11:21 AM, Paul Stovell <stov...@gmail.com> wrote:
>> If I'm not mistaken, I believe we created these patterns so we'd stop >> mixing UI logic code with logic code :-) Is the VM going to become The Next >> CodeBehind?
>> To put it another way, I think it risks mixing concerns. If I'm browsing >> the VM following the process for downloading the file and communicating >> whether it's done, I'd rather not see the code adding "%" after each number >> or an IsCancelButtonEnabled property. I'd much rather a ProgressPercentage >> integer property and a HasCompleted boolean property, and let the view >> convert it. The VM manages state, the view manages how it's visualized.
>> I think of the "state" of my VM as the conceptual state, not the real >> state. It's kind of like the difference between the Logical tree and the >> Visual tree, but at a domain level.
>> On Tue, Dec 2, 2008 at 2:38 AM, Josh Smith <flappleja...@gmail.com>wrote:
>>> A ViewModel is basically a value converter on steroids. I takes "raw" >>> data and converts it into something presentation-friendly, and vice-versa. >>> If you ever find yourself binding an element's property to a ViewModel's >>> property, and you're using a value converter, stop! Why not just create a >>> property on the ViewModel that exposes the "formatted" data, and then drop >>> the value converter altogether?
>>> The only place I can see a use for value converters in an MVVM >>> architecture is cross-element bindings. If I'm binding the Visibility of a >>> panel to the IsChecked of a CheckBox, then I will need to use the >>> BooleanToVisibilityConverter. But, perhaps even in that case I should take >>> the "high road" and bind the IsChecked to a property on the ViewModel, and >>> then have a SomePanelVisibility property on the VM, to which the Panel is >>> bound.
>> So, if I have a Customer class and want to make it easy to show an
instance via binding in WPF, I should have a CustomerModelView class. If I have an input form that shows a new Customer, I should create an abstraction of that View, called CustomerViewModel. This way, the CustomerViewModel would perform the View-specific formatting, since it wouldn't be reused anywhere. However, the CustomerModelView could be shared across multiple Views and ViewModels.
Can you explain this in more detail? What kinds of properties/behavior/logic would you see on each class?
Perhaps we could have a "disciples code off" to see each person's approach.
On Tue, Dec 2, 2008 at 3:10 AM, Josh Smith <flappleja...@gmail.com> wrote: > Bill,
> You're right about the multiple frameworks argument, but that's not my > goal, so I didn't factor it into my thought. To be honest, I'd be very > interested in seeing someone actually reuse a set of ViewModel classes in > WinForms, ASP.NET, and WPF. I'd be happy enough just to see someone reuse > them in WPF and SL. :)
> Your point about "friction" between multiple Views raises a long-standing > issue of mine. I think the terminology of MVVM is too limited. Really that > pattern should be Model-ModelView-View-ViewModel (MMVVVM). The distiction > between ModelView and ViewModel is the important point here. I've found > that many times I create a VM for a model object, such as CustomerViewModel > for Customer. I also create a ViewModel for a View object, such as > CustomerViewModel for CustomerView. The friction you described is > particular to the former case, where a "view model" is created for a model > object, but not for one particular View. This is a sore point in the MVVM > world.
> I think that it is better to call a presentation-friendly wrapper around a > Model object by its proper name: a ModelView. So, if I have a Customer > class and want to make it easy to show an instance via binding in WPF, I > should have a CustomerModelView class. If I have an input form that shows a > new Customer, I should create an abstraction of that View, called > CustomerViewModel. This way, the CustomerViewModel would perform the > View-specific formatting, since it wouldn't be reused anywhere. However, > the CustomerModelView could be shared across multiple Views and ViewModels.
> Josh
> On Mon, Dec 1, 2008 at 11:22 AM, Bill Kempf <weke...@gmail.com> wrote:
>> Yes... and no. I think that if you're reaching for a value converter, >> you do need to stop and think, because it's often simpler, cleaner and >> easier to maintain to just use a special property on the view model. >> However, there's reasons beyond the ones you've given to not go for a >> special property.
>> 1. If the value you need is unique to presentation, you should >> consider still using a converter. Visibility is a classic example. >> If one of your reasons to be using MVPoo is to be able to use multiple >> presentation frameworks (WPF, WinForms, WebForms, ASP.NET MVC, etc.) >> then the last thing you want to do is expose a property of type >> Visibility. Even if you're sticking to WPF, there's two possible >> "hidden" values with differing characteristics (hidden and collapsed). >> Choosing among these is a view concern, not a view model concern. >> (It actually bugs me that the BooleanToVisibilityConverter doesn't >> support this choice out of the box!)
>> 2. Formatting is generally a presentation concern, and should be >> handled by the view. It may be tempting to add a property that >> formats that date in some specific way, but down the road when you use >> a different view that wants to format that date in another way, you >> have friction between views that may not be easily resolved. Again, >> if the conversion is to facilitate presentation, let the view handle >> it.
>> On Mon, Dec 1, 2008 at 11:08 AM, Josh Smith <flappleja...@gmail.com> >> wrote: >> > A ViewModel is basically a value converter on steroids. I takes "raw" >> data >> > and converts it into something presentation-friendly, and vice-versa. >> If >> > you ever find yourself binding an element's property to a ViewModel's >> > property, and you're using a value converter, stop! Why not just create >> a >> > property on the ViewModel that exposes the "formatted" data, and then >> drop >> > the value converter altogether?
>> > The only place I can see a use for value converters in an MVVM >> architecture >> > is cross-element bindings. If I'm binding the Visibility of a panel to >> the >> > IsChecked of a CheckBox, then I will need to use the >> > BooleanToVisibilityConverter. But, perhaps even in that case I should >> take >> > the "high road" and bind the IsChecked to a property on the ViewModel, >> and >> > then have a SomePanelVisibility property on the VM, to which the Panel >> is >> > bound.
>> > Do you agree???
>> -- >> Quidquid latine dictum sit, altum sonatur. >> - Whatever is said in Latin sounds profound.
>> War is peace. Freedom is slavery. Bugs are features.
>> On Mon, Dec 1, 2008 at 11:08 AM, Josh Smith <flappleja...@gmail.com> >> wrote: >> > A ViewModel is basically a value converter on steroids. I takes "raw" >> data >> > and converts it into something presentation-friendly, and vice-versa. >> If >> > you ever find yourself binding an element's property to a ViewModel's >> > property, and you're using a value converter, stop! Why not just create >> a >> > property on the ViewModel that exposes the "formatted" data, and then >> drop >> > the value converter altogether?
>> > The only place I can see a use for value converters in an MVVM >> architecture >> > is cross-element bindings. If I'm binding the Visibility of a panel to >> the >> > IsChecked of a CheckBox, then I will need to use the >> > BooleanToVisibilityConverter. But, perhaps even in that case I should >> take >> > the "high road" and bind the IsChecked to a property on the ViewModel, >> and >> > then have a SomePanelVisibility property on the VM, to which the Panel >> is >> > bound.
>> > Do you agree???
>> -- >> Quidquid latine dictum sit, altum sonatur. >> - Whatever is said in Latin sounds profound.
>> War is peace. Freedom is slavery. Bugs are features.
>> I guess I see the VM as a way of shaping the domain model, rather than a
way of completely simplifying the view.
Extracting the behavior of a View into a ViewModel does more than simplify the View. I find that it makes it much easier to write unit tests that "pretend" to be the View. The tests become simply another consumer of the ViewModel, which allows them to help ensure that the UI will behave as expected, without ever having to deal with the added complexities of testing live visual elements.
Deciding how smart the various pieces of a system should be boils down to personal preference and philosophy. I can definitely see the benefits of offloading lots of View-oriented logic into value converters, or the code-behind, as you encourage. I simply find value converters to be hacky and mysterious. They are an anti-pattern, in my opinion.
Isn't it great that WPF is so flexible that we can have these discussions?!
On Mon, Dec 1, 2008 at 11:55 AM, Paul Stovell <stov...@gmail.com> wrote: > >> For example, I would never create a property in a code-behind and then > bind an element's property to it.
> So, I actually don't see a problem with that. Sometimes code-behind is a > perfectly adequate view model. Especially if that property is very UI > specific, such as whether a panel is collapsed.
> I guess the way I think about it is the state of the UI is different to the > state of the information making up the UI. A panel being open/closed is very > UI-specific, in my books, so I probably wouldn't include it. If it was based > on some information however - like whether a library book is overdue, then I > might expose a property such as "IsOverdue" which my panel's visibility is > based on. This comes down to how I want to seperate concerns - I want to > know whether George remembered to check whether the book was on hold before > making it available to borrow; not how he surfaced that in the UI.
> I guess I see the VM as a way of shaping the domain model, rather than a > way of completely simplifying the view.
> On Tue, Dec 2, 2008 at 3:03 AM, Josh Smith <flappleja...@gmail.com> wrote:
>> Paul,
>> I see what you mean. I don't see my suggestion as promoting the ViewModel >> as the next code-behind, though. The code-behind of a View still serves a >> purpose in MVVM, aside from what the VM does. For example, I would never >> create a property in a code-behind and then bind an element's property to >> it. To me, the state of the UI includes the state of the functional areas in >> the UI, such as whether some panel is open or closed. In my way of >> thinking, that state belongs in the ViewModel.
>> Josh
>> On Mon, Dec 1, 2008 at 11:21 AM, Paul Stovell <stov...@gmail.com> wrote:
>>> If I'm not mistaken, I believe we created these patterns so we'd stop >>> mixing UI logic code with logic code :-) Is the VM going to become The Next >>> CodeBehind?
>>> To put it another way, I think it risks mixing concerns. If I'm browsing >>> the VM following the process for downloading the file and communicating >>> whether it's done, I'd rather not see the code adding "%" after each number >>> or an IsCancelButtonEnabled property. I'd much rather a ProgressPercentage >>> integer property and a HasCompleted boolean property, and let the view >>> convert it. The VM manages state, the view manages how it's visualized.
>>> I think of the "state" of my VM as the conceptual state, not the real >>> state. It's kind of like the difference between the Logical tree and the >>> Visual tree, but at a domain level.
>>> On Tue, Dec 2, 2008 at 2:38 AM, Josh Smith <flappleja...@gmail.com>wrote:
>>>> A ViewModel is basically a value converter on steroids. I takes "raw" >>>> data and converts it into something presentation-friendly, and vice-versa. >>>> If you ever find yourself binding an element's property to a ViewModel's >>>> property, and you're using a value converter, stop! Why not just create a >>>> property on the ViewModel that exposes the "formatted" data, and then drop >>>> the value converter altogether?
>>>> The only place I can see a use for value converters in an MVVM >>>> architecture is cross-element bindings. If I'm binding the Visibility of a >>>> panel to the IsChecked of a CheckBox, then I will need to use the >>>> BooleanToVisibilityConverter. But, perhaps even in that case I should take >>>> the "high road" and bind the IsChecked to a property on the ViewModel, and >>>> then have a SomePanelVisibility property on the VM, to which the Panel is >>>> bound.
On Tue, Dec 2, 2008 at 3:35 AM, Josh Smith <flappleja...@gmail.com> wrote: > >> I guess I see the VM as a way of shaping the domain model, rather than a > way of completely simplifying the view.
> Extracting the behavior of a View into a ViewModel does more than simplify > the View. I find that it makes it much easier to write unit tests that > "pretend" to be the View. The tests become simply another consumer of the > ViewModel, which allows them to help ensure that the UI will behave as > expected, without ever having to deal with the added complexities of testing > live visual elements.
> Deciding how smart the various pieces of a system should be boils down to > personal preference and philosophy. I can definitely see the benefits of > offloading lots of View-oriented logic into value converters, or the > code-behind, as you encourage. I simply find value converters to be hacky > and mysterious. They are an anti-pattern, in my opinion.
> Isn't it great that WPF is so flexible that we can have these discussions?!
> Josh
> On Mon, Dec 1, 2008 at 11:55 AM, Paul Stovell <stov...@gmail.com> wrote:
>> >> For example, I would never create a property in a code-behind and then >> bind an element's property to it.
>> So, I actually don't see a problem with that. Sometimes code-behind is a >> perfectly adequate view model. Especially if that property is very UI >> specific, such as whether a panel is collapsed.
>> I guess the way I think about it is the state of the UI is different to >> the state of the information making up the UI. A panel being open/closed is >> very UI-specific, in my books, so I probably wouldn't include it. If it was >> based on some information however - like whether a library book is overdue, >> then I might expose a property such as "IsOverdue" which my panel's >> visibility is based on. This comes down to how I want to seperate concerns - >> I want to know whether George remembered to check whether the book was on >> hold before making it available to borrow; not how he surfaced that in the >> UI.
>> I guess I see the VM as a way of shaping the domain model, rather than a >> way of completely simplifying the view.
>> On Tue, Dec 2, 2008 at 3:03 AM, Josh Smith <flappleja...@gmail.com>wrote:
>>> Paul,
>>> I see what you mean. I don't see my suggestion as promoting the >>> ViewModel as the next code-behind, though. The code-behind of a View still >>> serves a purpose in MVVM, aside from what the VM does. For example, I would >>> never create a property in a code-behind and then bind an element's property >>> to it. To me, the state of the UI includes the state of the functional areas >>> in the UI, such as whether some panel is open or closed. In my way of >>> thinking, that state belongs in the ViewModel.
>>> Josh
>>> On Mon, Dec 1, 2008 at 11:21 AM, Paul Stovell <stov...@gmail.com> wrote:
>>>> If I'm not mistaken, I believe we created these patterns so we'd stop >>>> mixing UI logic code with logic code :-) Is the VM going to become The Next >>>> CodeBehind?
>>>> To put it another way, I think it risks mixing concerns. If I'm browsing >>>> the VM following the process for downloading the file and communicating >>>> whether it's done, I'd rather not see the code adding "%" after each number >>>> or an IsCancelButtonEnabled property. I'd much rather a ProgressPercentage >>>> integer property and a HasCompleted boolean property, and let the view >>>> convert it. The VM manages state, the view manages how it's visualized.
>>>> I think of the "state" of my VM as the conceptual state, not the real >>>> state. It's kind of like the difference between the Logical tree and the >>>> Visual tree, but at a domain level.
>>>> On Tue, Dec 2, 2008 at 2:38 AM, Josh Smith <flappleja...@gmail.com>wrote:
>>>>> A ViewModel is basically a value converter on steroids. I takes "raw" >>>>> data and converts it into something presentation-friendly, and vice-versa. >>>>> If you ever find yourself binding an element's property to a ViewModel's >>>>> property, and you're using a value converter, stop! Why not just create a >>>>> property on the ViewModel that exposes the "formatted" data, and then drop >>>>> the value converter altogether?
>>>>> The only place I can see a use for value converters in an MVVM >>>>> architecture is cross-element bindings. If I'm binding the Visibility of a >>>>> panel to the IsChecked of a CheckBox, then I will need to use the >>>>> BooleanToVisibilityConverter. But, perhaps even in that case I should take >>>>> the "high road" and bind the IsChecked to a property on the ViewModel, and >>>>> then have a SomePanelVisibility property on the VM, to which the Panel is >>>>> bound.
Suppose the Customer class exposes each value as a getXYZ() method. The CustomerModelView (CMV) would then wrap each of them into a property. The CustomerViewModel (CMV) would be responsible for putting all the CMVs into an observable collection, provide aggregation values (i.e. total sales, etc) and CustomerView (CV) would be responsible for showing them all in a sexy WPF-ified way. :)
Suppose Customer has properties, not methods, but many of them store indici which can be used to retrieve values by look-up form other objects. The CMV would expose properties that internally perform the lookups.
Suppose Customer has validation logic that throws exceptions if a property is set to an invalid value. CMV would catch those exceptions and implement IDataErrorInfo to provide a soft, clean form of object validation.
In each of these situations, the ModelView (not the ViewModel) acts as a ViewModel-agnostic adapter around a Model object.
On Mon, Dec 1, 2008 at 12:04 PM, Paul Stovell <stov...@gmail.com> wrote: > Hi Josh,
> I'm interested in this scenario:
> >> So, if I have a Customer class and want to make it easy to show an > instance via binding in WPF, I should have a CustomerModelView class. If I > have an input form that shows a new Customer, I should create an abstraction > of that View, called CustomerViewModel. This way, the CustomerViewModel > would perform the View-specific formatting, since it wouldn't be reused > anywhere. However, the CustomerModelView could be shared across multiple > Views and ViewModels.
> Can you explain this in more detail? What kinds of > properties/behavior/logic would you see on each class?
> Perhaps we could have a "disciples code off" to see each person's approach.
> Paul
> On Tue, Dec 2, 2008 at 3:10 AM, Josh Smith <flappleja...@gmail.com> wrote:
>> Bill,
>> You're right about the multiple frameworks argument, but that's not my >> goal, so I didn't factor it into my thought. To be honest, I'd be very >> interested in seeing someone actually reuse a set of ViewModel classes in >> WinForms, ASP.NET, and WPF. I'd be happy enough just to see someone >> reuse them in WPF and SL. :)
>> Your point about "friction" between multiple Views raises a long-standing >> issue of mine. I think the terminology of MVVM is too limited. Really that >> pattern should be Model-ModelView-View-ViewModel (MMVVVM). The distiction >> between ModelView and ViewModel is the important point here. I've found >> that many times I create a VM for a model object, such as CustomerViewModel >> for Customer. I also create a ViewModel for a View object, such as >> CustomerViewModel for CustomerView. The friction you described is >> particular to the former case, where a "view model" is created for a model >> object, but not for one particular View. This is a sore point in the MVVM >> world.
>> I think that it is better to call a presentation-friendly wrapper around a >> Model object by its proper name: a ModelView. So, if I have a Customer >> class and want to make it easy to show an instance via binding in WPF, I >> should have a CustomerModelView class. If I have an input form that shows a >> new Customer, I should create an abstraction of that View, called >> CustomerViewModel. This way, the CustomerViewModel would perform the >> View-specific formatting, since it wouldn't be reused anywhere. However, >> the CustomerModelView could be shared across multiple Views and ViewModels.
>> Josh
>> On Mon, Dec 1, 2008 at 11:22 AM, Bill Kempf <weke...@gmail.com> wrote:
>>> Yes... and no. I think that if you're reaching for a value converter, >>> you do need to stop and think, because it's often simpler, cleaner and >>> easier to maintain to just use a special property on the view model. >>> However, there's reasons beyond the ones you've given to not go for a >>> special property.
>>> 1. If the value you need is unique to presentation, you should >>> consider still using a converter. Visibility is a classic example. >>> If one of your reasons to be using MVPoo is to be able to use multiple >>> presentation frameworks (WPF, WinForms, WebForms, ASP.NET MVC, etc.) >>> then the last thing you want to do is expose a property of type >>> Visibility. Even if you're sticking to WPF, there's two possible >>> "hidden" values with differing characteristics (hidden and collapsed). >>> Choosing among these is a view concern, not a view model concern. >>> (It actually bugs me that the BooleanToVisibilityConverter doesn't >>> support this choice out of the box!)
>>> 2. Formatting is generally a presentation concern, and should be >>> handled by the view. It may be tempting to add a property that >>> formats that date in some specific way, but down the road when you use >>> a different view that wants to format that date in another way, you >>> have friction between views that may not be easily resolved. Again, >>> if the conversion is to facilitate presentation, let the view handle >>> it.
>>> On Mon, Dec 1, 2008 at 11:08 AM, Josh Smith <flappleja...@gmail.com> >>> wrote: >>> > A ViewModel is basically a value converter on steroids. I takes "raw" >>> data >>> > and converts it into something presentation-friendly, and vice-versa. >>> If >>> > you ever find yourself binding an element's property to a ViewModel's >>> > property, and you're using a value converter, stop! Why not just >>> create a >>> > property on the ViewModel that exposes the "formatted" data, and then >>> drop >>> > the value converter altogether?
>>> > The only place I can see a use for value converters in an MVVM >>> architecture >>> > is cross-element bindings. If I'm binding the Visibility of a panel to >>> the >>> > IsChecked of a CheckBox, then I will need to use the >>> > BooleanToVisibilityConverter. But, perhaps even in that case I should >>> take >>> > the "high road" and bind the IsChecked to a property on the ViewModel, >>> and >>> > then have a SomePanelVisibility property on the VM, to which the Panel >>> is >>> > bound.
>>> > Do you agree???
>>> -- >>> Quidquid latine dictum sit, altum sonatur. >>> - Whatever is said in Latin sounds profound.
>>> War is peace. Freedom is slavery. Bugs are features.
>>> On Mon, Dec 1, 2008 at 11:08 AM, Josh Smith <flappleja...@gmail.com> >>> wrote: >>> > A ViewModel is basically a value converter on steroids. I takes "raw" >>> data >>> > and converts it into something presentation-friendly, and vice-versa. >>> If >>> > you ever find yourself binding an element's property to a ViewModel's >>> > property, and you're using a value converter, stop! Why not just >>> create a >>> > property on the ViewModel that exposes the "formatted" data, and then >>> drop >>> > the value converter altogether?
>>> > The only place I can see a use for value converters in an MVVM >>> architecture >>> > is cross-element bindings. If I'm binding the Visibility of a panel to >>> the >>> > IsChecked of a CheckBox, then I will need to use the >>> > BooleanToVisibilityConverter. But, perhaps even in that case I should >>> take >>> > the "high road" and bind the IsChecked to a property on the ViewModel, >>> and >>> > then have a SomePanelVisibility property on the VM, to which the Panel >>> is >>> > bound.
>>> > Do you agree???
>>> -- >>> Quidquid latine dictum sit, altum sonatur. >>> - Whatever is said in Latin sounds profound.
>>> War is peace. Freedom is slavery. Bugs are features.
As a general pattern, I'd say the ModelView is really just another part of the model - it just happens to be derived or adapting an existing object, but it may not always be. If you refactored it later to remove the messy Customer class, your ModelView might not make so much sense. In a similar situation, if my objects were based on DataRows in a legacy DataSet, I'd consider both the DS and the objects as part of the model. Perhaps just "CustomerAdapter"?
For a specific problem like that, for adapters, I always think of TypeDescriptor Providers. It would be trivial to build a very generic adapter to turn those methods into properties and exceptions into IDataErrorInfo, and you'd only code it once.
On Tue, Dec 2, 2008 at 3:41 AM, Josh Smith <flappleja...@gmail.com> wrote: > Sure thing.
> Suppose the Customer class exposes each value as a getXYZ() method. The > CustomerModelView (CMV) would then wrap each of them into a property. The > CustomerViewModel (CMV) would be responsible for putting all the CMVs into > an observable collection, provide aggregation values (i.e. total sales, etc) > and CustomerView (CV) would be responsible for showing them all in a sexy > WPF-ified way. :)
> Suppose Customer has properties, not methods, but many of them store indici > which can be used to retrieve values by look-up form other objects. The CMV > would expose properties that internally perform the lookups.
> Suppose Customer has validation logic that throws exceptions if a property > is set to an invalid value. CMV would catch those exceptions and implement > IDataErrorInfo to provide a soft, clean form of object validation.
> In each of these situations, the ModelView (not the ViewModel) acts as a > ViewModel-agnostic adapter around a Model object.
> Josh
> On Mon, Dec 1, 2008 at 12:04 PM, Paul Stovell <stov...@gmail.com> wrote:
>> Hi Josh,
>> I'm interested in this scenario:
>> >> So, if I have a Customer class and want to make it easy to show an >> instance via binding in WPF, I should have a CustomerModelView class. If I >> have an input form that shows a new Customer, I should create an abstraction >> of that View, called CustomerViewModel. This way, the CustomerViewModel >> would perform the View-specific formatting, since it wouldn't be reused >> anywhere. However, the CustomerModelView could be shared across multiple >> Views and ViewModels.
>> Can you explain this in more detail? What kinds of >> properties/behavior/logic would you see on each class?
>> Perhaps we could have a "disciples code off" to see each person's >> approach.
>> Paul
>> On Tue, Dec 2, 2008 at 3:10 AM, Josh Smith <flappleja...@gmail.com>wrote:
>>> Bill,
>>> You're right about the multiple frameworks argument, but that's not my >>> goal, so I didn't factor it into my thought. To be honest, I'd be very >>> interested in seeing someone actually reuse a set of ViewModel classes in >>> WinForms, ASP.NET, and WPF. I'd be happy enough just to see someone >>> reuse them in WPF and SL. :)
>>> Your point about "friction" between multiple Views raises a long-standing >>> issue of mine. I think the terminology of MVVM is too limited. Really that >>> pattern should be Model-ModelView-View-ViewModel (MMVVVM). The distiction >>> between ModelView and ViewModel is the important point here. I've found >>> that many times I create a VM for a model object, such as CustomerViewModel >>> for Customer. I also create a ViewModel for a View object, such as >>> CustomerViewModel for CustomerView. The friction you described is >>> particular to the former case, where a "view model" is created for a model >>> object, but not for one particular View. This is a sore point in the MVVM >>> world.
>>> I think that it is better to call a presentation-friendly wrapper around >>> a Model object by its proper name: a ModelView. So, if I have a Customer >>> class and want to make it easy to show an instance via binding in WPF, I >>> should have a CustomerModelView class. If I have an input form that shows a >>> new Customer, I should create an abstraction of that View, called >>> CustomerViewModel. This way, the CustomerViewModel would perform the >>> View-specific formatting, since it wouldn't be reused anywhere. However, >>> the CustomerModelView could be shared across multiple Views and ViewModels.
>>> Josh
>>> On Mon, Dec 1, 2008 at 11:22 AM, Bill Kempf <weke...@gmail.com> wrote:
>>>> Yes... and no. I think that if you're reaching for a value converter, >>>> you do need to stop and think, because it's often simpler, cleaner and >>>> easier to maintain to just use a special property on the view model. >>>> However, there's reasons beyond the ones you've given to not go for a >>>> special property.
>>>> 1. If the value you need is unique to presentation, you should >>>> consider still using a converter. Visibility is a classic example. >>>> If one of your reasons to be using MVPoo is to be able to use multiple >>>> presentation frameworks (WPF, WinForms, WebForms, ASP.NET MVC, etc.) >>>> then the last thing you want to do is expose a property of type >>>> Visibility. Even if you're sticking to WPF, there's two possible >>>> "hidden" values with differing characteristics (hidden and collapsed). >>>> Choosing among these is a view concern, not a view model concern. >>>> (It actually bugs me that the BooleanToVisibilityConverter doesn't >>>> support this choice out of the box!)
>>>> 2. Formatting is generally a presentation concern, and should be >>>> handled by the view. It may be tempting to add a property that >>>> formats that date in some specific way, but down the road when you use >>>> a different view that wants to format that date in another way, you >>>> have friction between views that may not be easily resolved. Again, >>>> if the conversion is to facilitate presentation, let the view handle >>>> it.
>>>> On Mon, Dec 1, 2008 at 11:08 AM, Josh Smith <flappleja...@gmail.com> >>>> wrote: >>>> > A ViewModel is basically a value converter on steroids. I takes "raw" >>>> data >>>> > and converts it into something presentation-friendly, and vice-versa. >>>> If >>>> > you ever find yourself binding an element's property to a ViewModel's >>>> > property, and you're using a value converter, stop! Why not just >>>> create a >>>> > property on the ViewModel that exposes the "formatted" data, and then >>>> drop >>>> > the value converter altogether?
>>>> > The only place I can see a use for value converters in an MVVM >>>> architecture >>>> > is cross-element bindings. If I'm binding the Visibility of a panel >>>> to the >>>> > IsChecked of a CheckBox, then I will need to use the >>>> > BooleanToVisibilityConverter. But, perhaps even in that case I should >>>> take >>>> > the "high road" and bind the IsChecked to a property on the ViewModel, >>>> and >>>> > then have a SomePanelVisibility property on the VM, to which the Panel >>>> is >>>> > bound.
>>>> > Do you agree???
>>>> -- >>>> Quidquid latine dictum sit, altum sonatur. >>>> - Whatever is said in Latin sounds profound.
>>>> War is peace. Freedom is slavery. Bugs are features.
>>>> On Mon, Dec 1, 2008 at 11:08 AM, Josh Smith <flappleja...@gmail.com> >>>> wrote: >>>> > A ViewModel is basically a value converter on steroids. I takes "raw" >>>> data >>>> > and converts it into something presentation-friendly, and vice-versa. >>>> If >>>> > you ever find yourself binding an element's property to a ViewModel's >>>> > property, and you're using a value converter, stop! Why not just >>>> create a >>>> > property on the ViewModel that exposes the "formatted" data, and then >>>> drop >>>> > the value converter altogether?
>>>> > The only place I can see a use for value converters in an MVVM >>>> architecture >>>> > is cross-element bindings. If I'm binding the Visibility of a panel >>>> to the >>>> > IsChecked of a CheckBox, then I will need to use the >>>> > BooleanToVisibilityConverter. But, perhaps even in that case I should >>>> take >>>> > the "high road" and bind the IsChecked to a property on the ViewModel, >>>> and >>>> > then have a SomePanelVisibility property on the VM, to which the Panel >>>> is >>>> > bound.
>>>> > Do you agree???
>>>> -- >>>> Quidquid latine dictum sit, altum sonatur. >>>> - Whatever is said in Latin sounds profound.
>>>> War is peace. Freedom is slavery. Bugs are features.
I'm not familiar with TypeDescriptor Providers, I will have to check that out. I agree that ideally you should refactor those "difficult" Model classes, but that's not always an option. Many times, especially in large companies, Model classes are inherited from other systems or the new system's predecessor, and cannot be modified.
On Mon, Dec 1, 2008 at 12:22 PM, Paul Stovell <stov...@gmail.com> wrote: > As a general pattern, I'd say the ModelView is really just another part of > the model - it just happens to be derived or adapting an existing object, > but it may not always be. If you refactored it later to remove the messy > Customer class, your ModelView might not make so much sense. In a similar > situation, if my objects were based on DataRows in a legacy DataSet, I'd > consider both the DS and the objects as part of the model. Perhaps just > "CustomerAdapter"?
> For a specific problem like that, for adapters, I always think of > TypeDescriptor Providers. It would be trivial to build a very generic > adapter to turn those methods into properties and exceptions into > IDataErrorInfo, and you'd only code it once.
> On Tue, Dec 2, 2008 at 3:41 AM, Josh Smith <flappleja...@gmail.com> wrote:
>> Sure thing.
>> Suppose the Customer class exposes each value as a getXYZ() method. The >> CustomerModelView (CMV) would then wrap each of them into a property. The >> CustomerViewModel (CMV) would be responsible for putting all the CMVs into >> an observable collection, provide aggregation values (i.e. total sales, etc) >> and CustomerView (CV) would be responsible for showing them all in a sexy >> WPF-ified way. :)
>> Suppose Customer has properties, not methods, but many of them store >> indici which can be used to retrieve values by look-up form other objects. >> The CMV would expose properties that internally perform the lookups.
>> Suppose Customer has validation logic that throws exceptions if a property >> is set to an invalid value. CMV would catch those exceptions and implement >> IDataErrorInfo to provide a soft, clean form of object validation.
>> In each of these situations, the ModelView (not the ViewModel) acts as a >> ViewModel-agnostic adapter around a Model object.
>> Josh
>> On Mon, Dec 1, 2008 at 12:04 PM, Paul Stovell <stov...@gmail.com> wrote:
>>> Hi Josh,
>>> I'm interested in this scenario:
>>> >> So, if I have a Customer class and want to make it easy to show an >>> instance via binding in WPF, I should have a CustomerModelView class. If I >>> have an input form that shows a new Customer, I should create an abstraction >>> of that View, called CustomerViewModel. This way, the CustomerViewModel >>> would perform the View-specific formatting, since it wouldn't be reused >>> anywhere. However, the CustomerModelView could be shared across multiple >>> Views and ViewModels.
>>> Can you explain this in more detail? What kinds of >>> properties/behavior/logic would you see on each class?
>>> Perhaps we could have a "disciples code off" to see each person's >>> approach.
>>> Paul
>>> On Tue, Dec 2, 2008 at 3:10 AM, Josh Smith <flappleja...@gmail.com>wrote:
>>>> Bill,
>>>> You're right about the multiple frameworks argument, but that's not my >>>> goal, so I didn't factor it into my thought. To be honest, I'd be very >>>> interested in seeing someone actually reuse a set of ViewModel classes in >>>> WinForms, ASP.NET, and WPF. I'd be happy enough just to see someone >>>> reuse them in WPF and SL. :)
>>>> Your point about "friction" between multiple Views raises a >>>> long-standing issue of mine. I think the terminology of MVVM is too >>>> limited. Really that pattern should be Model-ModelView-View-ViewModel >>>> (MMVVVM). The distiction between ModelView and ViewModel is the important >>>> point here. I've found that many times I create a VM for a model object, >>>> such as CustomerViewModel for Customer. I also create a ViewModel for a >>>> View object, such as CustomerViewModel for CustomerView. The friction you >>>> described is particular to the former case, where a "view model" is created >>>> for a model object, but not for one particular View. This is a sore point >>>> in the MVVM world.
>>>> I think that it is better to call a presentation-friendly wrapper around >>>> a Model object by its proper name: a ModelView. So, if I have a Customer >>>> class and want to make it easy to show an instance via binding in WPF, I >>>> should have a CustomerModelView class. If I have an input form that shows a >>>> new Customer, I should create an abstraction of that View, called >>>> CustomerViewModel. This way, the CustomerViewModel would perform the >>>> View-specific formatting, since it wouldn't be reused anywhere. However, >>>> the CustomerModelView could be shared across multiple Views and ViewModels.
>>>> Josh
>>>> On Mon, Dec 1, 2008 at 11:22 AM, Bill Kempf <weke...@gmail.com> wrote:
>>>>> Yes... and no. I think that if you're reaching for a value converter, >>>>> you do need to stop and think, because it's often simpler, cleaner and >>>>> easier to maintain to just use a special property on the view model. >>>>> However, there's reasons beyond the ones you've given to not go for a >>>>> special property.
>>>>> 1. If the value you need is unique to presentation, you should >>>>> consider still using a converter. Visibility is a classic example. >>>>> If one of your reasons to be using MVPoo is to be able to use multiple >>>>> presentation frameworks (WPF, WinForms, WebForms, ASP.NET MVC, etc.) >>>>> then the last thing you want to do is expose a property of type >>>>> Visibility. Even if you're sticking to WPF, there's two possible >>>>> "hidden" values with differing characteristics (hidden and collapsed). >>>>> Choosing among these is a view concern, not a view model concern. >>>>> (It actually bugs me that the BooleanToVisibilityConverter doesn't >>>>> support this choice out of the box!)
>>>>> 2. Formatting is generally a presentation concern, and should be >>>>> handled by the view. It may be tempting to add a property that >>>>> formats that date in some specific way, but down the road when you use >>>>> a different view that wants to format that date in another way, you >>>>> have friction between views that may not be easily resolved. Again, >>>>> if the conversion is to facilitate presentation, let the view handle >>>>> it.
>>>>> On Mon, Dec 1, 2008 at 11:08 AM, Josh Smith <flappleja...@gmail.com> >>>>> wrote: >>>>> > A ViewModel is basically a value converter on steroids. I takes >>>>> "raw" data >>>>> > and converts it into something presentation-friendly, and vice-versa. >>>>> If >>>>> > you ever find yourself binding an element's property to a ViewModel's >>>>> > property, and you're using a value converter, stop! Why not just >>>>> create a >>>>> > property on the ViewModel that exposes the "formatted" data, and then >>>>> drop >>>>> > the value converter altogether?
>>>>> > The only place I can see a use for value converters in an MVVM >>>>> architecture >>>>> > is cross-element bindings. If I'm binding the Visibility of a panel >>>>> to the >>>>> > IsChecked of a CheckBox, then I will need to use the >>>>> > BooleanToVisibilityConverter. But, perhaps even in that case I >>>>> should take >>>>> > the "high road" and bind the IsChecked to a property on the >>>>> ViewModel, and >>>>> > then have a SomePanelVisibility property on the VM, to which the >>>>> Panel is >>>>> > bound.
>>>>> > Do you agree???
>>>>> -- >>>>> Quidquid latine dictum sit, altum sonatur. >>>>> - Whatever is said in Latin sounds profound.
>>>>> War is peace. Freedom is slavery. Bugs are features.
>>>>> On Mon, Dec 1, 2008 at 11:08 AM, Josh Smith <flappleja...@gmail.com> >>>>> wrote: >>>>> > A ViewModel is basically a value converter on steroids. I takes >>>>> "raw" data >>>>> > and converts it into something presentation-friendly, and vice-versa. >>>>> If >>>>> > you ever find yourself binding an element's property to a ViewModel's >>>>> > property, and you're using a value converter, stop! Why not just >>>>> create a >>>>> > property on the ViewModel that exposes the "formatted" data, and then >>>>> drop >>>>> > the value converter altogether?
>>>>> > The only place I can see a use for value converters in an MVVM >>>>> architecture >>>>> > is cross-element bindings. If I'm binding the Visibility of a panel >>>>> to the >>>>> > IsChecked of a CheckBox, then I will need to use the >>>>> > BooleanToVisibilityConverter. But, perhaps even in that case I >>>>> should take >>>>> > the "high road" and bind the IsChecked to a property on the >>>>> ViewModel, and >>>>> > then have a SomePanelVisibility property on the VM, to which the >>>>> Panel is >>>>> > bound.
>>>>> > Do you agree???
>>>>> -- >>>>> Quidquid latine dictum sit, altum sonatur. >>>>> - Whatever is said in Latin sounds profound.
>>>>> War is peace. Freedom is slavery. Bugs are features.
TypeDescriptor Providers are in-friggin-credible. I use them to create bindable property bags. But I also discovered that you can use an adapter to front an object as a dependency object and dynamically generate dependency properties to provide the same effect. And because dependency properties work with the binding system, they even work in non-wpf scenarios. I have a nagging suspicion that under the hood, dependency properties use the TypeDescriptor system. Wrote a quick blurb about it here<http://mbrownchicago.spaces.live.com/blog/cns!2221DC39E0C749A4!668.en...>. Never got around to sanitizing the code before leaving the last place :P
On Mon, Dec 1, 2008 at 12:47 PM, Josh Smith <flappleja...@gmail.com> wrote: > I'm not familiar with TypeDescriptor Providers, I will have to check that > out. I agree that ideally you should refactor those "difficult" Model > classes, but that's not always an option. Many times, especially in large > companies, Model classes are inherited from other systems or the new > system's predecessor, and cannot be modified.
> Josh
> On Mon, Dec 1, 2008 at 12:22 PM, Paul Stovell <stov...@gmail.com> wrote:
>> As a general pattern, I'd say the ModelView is really just another part of >> the model - it just happens to be derived or adapting an existing object, >> but it may not always be. If you refactored it later to remove the messy >> Customer class, your ModelView might not make so much sense. In a similar >> situation, if my objects were based on DataRows in a legacy DataSet, I'd >> consider both the DS and the objects as part of the model. Perhaps just >> "CustomerAdapter"?
>> For a specific problem like that, for adapters, I always think of >> TypeDescriptor Providers. It would be trivial to build a very generic >> adapter to turn those methods into properties and exceptions into >> IDataErrorInfo, and you'd only code it once.
>> On Tue, Dec 2, 2008 at 3:41 AM, Josh Smith <flappleja...@gmail.com>wrote:
>>> Sure thing.
>>> Suppose the Customer class exposes each value as a getXYZ() method. The >>> CustomerModelView (CMV) would then wrap each of them into a property. The >>> CustomerViewModel (CMV) would be responsible for putting all the CMVs into >>> an observable collection, provide aggregation values (i.e. total sales, etc) >>> and CustomerView (CV) would be responsible for showing them all in a sexy >>> WPF-ified way. :)
>>> Suppose Customer has properties, not methods, but many of them store >>> indici which can be used to retrieve values by look-up form other objects. >>> The CMV would expose properties that internally perform the lookups.
>>> Suppose Customer has validation logic that throws exceptions if a >>> property is set to an invalid value. CMV would catch those exceptions and >>> implement IDataErrorInfo to provide a soft, clean form of object validation.
>>> In each of these situations, the ModelView (not the ViewModel) acts as a >>> ViewModel-agnostic adapter around a Model object.
>>> Josh
>>> On Mon, Dec 1, 2008 at 12:04 PM, Paul Stovell <stov...@gmail.com> wrote:
>>>> Hi Josh,
>>>> I'm interested in this scenario:
>>>> >> So, if I have a Customer class and want to make it easy to show an >>>> instance via binding in WPF, I should have a CustomerModelView class. If I >>>> have an input form that shows a new Customer, I should create an abstraction >>>> of that View, called CustomerViewModel. This way, the CustomerViewModel >>>> would perform the View-specific formatting, since it wouldn't be reused >>>> anywhere. However, the CustomerModelView could be shared across multiple >>>> Views and ViewModels.
>>>> Can you explain this in more detail? What kinds of >>>> properties/behavior/logic would you see on each class?
>>>> Perhaps we could have a "disciples code off" to see each person's >>>> approach.
>>>> Paul
>>>> On Tue, Dec 2, 2008 at 3:10 AM, Josh Smith <flappleja...@gmail.com>wrote:
>>>>> Bill,
>>>>> You're right about the multiple frameworks argument, but that's not my >>>>> goal, so I didn't factor it into my thought. To be honest, I'd be very >>>>> interested in seeing someone actually reuse a set of ViewModel classes in >>>>> WinForms, ASP.NET <http://asp.net/>, and WPF. I'd be happy enough >>>>> just to see someone reuse them in WPF and SL. :)
>>>>> Your point about "friction" between multiple Views raises a >>>>> long-standing issue of mine. I think the terminology of MVVM is too >>>>> limited. Really that pattern should be Model-ModelView-View-ViewModel >>>>> (MMVVVM). The distiction between ModelView and ViewModel is the important >>>>> point here. I've found that many times I create a VM for a model object, >>>>> such as CustomerViewModel for Customer. I also create a ViewModel for a >>>>> View object, such as CustomerViewModel for CustomerView. The friction you >>>>> described is particular to the former case, where a "view model" is created >>>>> for a model object, but not for one particular View. This is a sore point >>>>> in the MVVM world.
>>>>> I think that it is better to call a presentation-friendly wrapper >>>>> around a Model object by its proper name: a ModelView. So, if I have a >>>>> Customer class and want to make it easy to show an instance via binding in >>>>> WPF, I should have a CustomerModelView class. If I have an input form that >>>>> shows a new Customer, I should create an abstraction of that View, called >>>>> CustomerViewModel. This way, the CustomerViewModel would perform the >>>>> View-specific formatting, since it wouldn't be reused anywhere. However, >>>>> the CustomerModelView could be shared across multiple Views and ViewModels.
>>>>> Josh
>>>>> On Mon, Dec 1, 2008 at 11:22 AM, Bill Kempf <weke...@gmail.com> wrote:
>>>>>> Yes... and no. I think that if you're reaching for a value converter, >>>>>> you do need to stop and think, because it's often simpler, cleaner and >>>>>> easier to maintain to just use a special property on the view model. >>>>>> However, there's reasons beyond the ones you've given to not go for a >>>>>> special property.
>>>>>> 1. If the value you need is unique to presentation, you should >>>>>> consider still using a converter. Visibility is a classic example. >>>>>> If one of your reasons to be using MVPoo is to be able to use multiple >>>>>> presentation frameworks (WPF, WinForms, WebForms, ASP.NET<http://asp.net/>MVC, etc.) >>>>>> then the last thing you want to do is expose a property of type >>>>>> Visibility. Even if you're sticking to WPF, there's two possible >>>>>> "hidden" values with differing characteristics (hidden and collapsed). >>>>>> Choosing among these is a view concern, not a view model concern. >>>>>> (It actually bugs me that the BooleanToVisibilityConverter doesn't >>>>>> support this choice out of the box!)
>>>>>> 2. Formatting is generally a presentation concern, and should be >>>>>> handled by the view. It may be tempting to add a property that >>>>>> formats that date in some specific way, but down the road when you use >>>>>> a different view that wants to format that date in another way, you >>>>>> have friction between views that may not be easily resolved. Again, >>>>>> if the conversion is to facilitate presentation, let the view handle >>>>>> it.
>>>>>> On Mon, Dec 1, 2008 at 11:08 AM, Josh Smith <flappleja...@gmail.com> >>>>>> wrote: >>>>>> > A ViewModel is basically a value converter on steroids. I takes >>>>>> "raw" data >>>>>> > and converts it into something presentation-friendly, and >>>>>> vice-versa. If >>>>>> > you ever find yourself binding an element's property to a >>>>>> ViewModel's >>>>>> > property, and you're using a value converter, stop! Why not just >>>>>> create a >>>>>> > property on the ViewModel that exposes the "formatted" data, and >>>>>> then drop >>>>>> > the value converter altogether?
>>>>>> > The only place I can see a use for value converters in an MVVM >>>>>> architecture >>>>>> > is cross-element bindings. If I'm binding the Visibility of a panel >>>>>> to the >>>>>> > IsChecked of a CheckBox, then I will need to use the >>>>>> > BooleanToVisibilityConverter. But, perhaps even in that case I >>>>>> should take >>>>>> > the "high road" and bind the IsChecked to a property on the >>>>>> ViewModel, and >>>>>> > then have a SomePanelVisibility property on the VM, to which the >>>>>> Panel is >>>>>> > bound.
>>>>>> > Do you agree???
>>>>>> -- >>>>>> Quidquid latine dictum sit, altum sonatur. >>>>>> - Whatever is said in Latin sounds profound.
>>>>>> War is peace. Freedom is slavery. Bugs are features.
>>>>>> On Mon, Dec 1, 2008 at 11:08 AM, Josh Smith <flappleja...@gmail.com> >>>>>> wrote: >>>>>> > A ViewModel is basically a value converter on steroids. I takes >>>>>> "raw" data >>>>>> > and converts it into something presentation-friendly, and >>>>>> vice-versa. If >>>>>> > you ever find yourself binding an element's property to a >>>>>> ViewModel's >>>>>> > property, and you're using a value converter, stop! Why not just >>>>>> create a >>>>>> > property on the ViewModel that exposes the "formatted" data, and >>>>>> then drop >>>>>> > the value converter altogether?
>>>>>> > The only place I can see a use for value converters in an MVVM >>>>>> architecture >>>>>> > is cross-element bindings. If I'm binding the Visibility of a panel >>>>>> to the >>>>>> > IsChecked of a CheckBox, then I will need to use the >>>>>> > BooleanToVisibilityConverter. But, perhaps even in that case I >>>>>> should take >>>>>> > the "high road" and bind the IsChecked to a property on the >>>>>> ViewModel, and >>>>>> > then have a SomePanelVisibility property on the VM, to which the >>>>>> Panel is >>>>>> > bound.
On Mon, Dec 1, 2008 at 1:59 PM, Mike Brown <mbrow...@gmail.com> wrote: > TypeDescriptor Providers are in-friggin-credible. I use them to create > bindable property bags. But I also discovered that you can use an adapter to > front an object as a dependency object and dynamically generate dependency > properties to provide the same effect. And because dependency properties > work with the binding system, they even work in non-wpf scenarios. I have a > nagging suspicion that under the hood, dependency properties use the > TypeDescriptor system. Wrote a quick blurb about it here<http://mbrownchicago.spaces.live.com/blog/cns!2221DC39E0C749A4!668.en...>. > Never got around to sanitizing the code before leaving the last place :P
> On Mon, Dec 1, 2008 at 12:47 PM, Josh Smith <flappleja...@gmail.com>wrote:
>> I'm not familiar with TypeDescriptor Providers, I will have to check that >> out. I agree that ideally you should refactor those "difficult" Model >> classes, but that's not always an option. Many times, especially in large >> companies, Model classes are inherited from other systems or the new >> system's predecessor, and cannot be modified.
>> Josh
>> On Mon, Dec 1, 2008 at 12:22 PM, Paul Stovell <stov...@gmail.com> wrote:
>>> As a general pattern, I'd say the ModelView is really just another part >>> of the model - it just happens to be derived or adapting an existing object, >>> but it may not always be. If you refactored it later to remove the messy >>> Customer class, your ModelView might not make so much sense. In a similar >>> situation, if my objects were based on DataRows in a legacy DataSet, I'd >>> consider both the DS and the objects as part of the model. Perhaps just >>> "CustomerAdapter"?
>>> For a specific problem like that, for adapters, I always think of >>> TypeDescriptor Providers. It would be trivial to build a very generic >>> adapter to turn those methods into properties and exceptions into >>> IDataErrorInfo, and you'd only code it once.
>>> On Tue, Dec 2, 2008 at 3:41 AM, Josh Smith <flappleja...@gmail.com>wrote:
>>>> Sure thing.
>>>> Suppose the Customer class exposes each value as a getXYZ() method. The >>>> CustomerModelView (CMV) would then wrap each of them into a property. The >>>> CustomerViewModel (CMV) would be responsible for putting all the CMVs into >>>> an observable collection, provide aggregation values (i.e. total sales, etc) >>>> and CustomerView (CV) would be responsible for showing them all in a sexy >>>> WPF-ified way. :)
>>>> Suppose Customer has properties, not methods, but many of them store >>>> indici which can be used to retrieve values by look-up form other objects. >>>> The CMV would expose properties that internally perform the lookups.
>>>> Suppose Customer has validation logic that throws exceptions if a >>>> property is set to an invalid value. CMV would catch those exceptions and >>>> implement IDataErrorInfo to provide a soft, clean form of object validation.
>>>> In each of these situations, the ModelView (not the ViewModel) acts as a >>>> ViewModel-agnostic adapter around a Model object.
>>>> Josh
>>>> On Mon, Dec 1, 2008 at 12:04 PM, Paul Stovell <stov...@gmail.com>wrote:
>>>>> Hi Josh,
>>>>> I'm interested in this scenario:
>>>>> >> So, if I have a Customer class and want to make it easy to show an >>>>> instance via binding in WPF, I should have a CustomerModelView class. If I >>>>> have an input form that shows a new Customer, I should create an abstraction >>>>> of that View, called CustomerViewModel. This way, the CustomerViewModel >>>>> would perform the View-specific formatting, since it wouldn't be reused >>>>> anywhere. However, the CustomerModelView could be shared across multiple >>>>> Views and ViewModels.
>>>>> Can you explain this in more detail? What kinds of >>>>> properties/behavior/logic would you see on each class?
>>>>> Perhaps we could have a "disciples code off" to see each person's >>>>> approach.
>>>>> Paul
>>>>> On Tue, Dec 2, 2008 at 3:10 AM, Josh Smith <flappleja...@gmail.com>wrote:
>>>>>> Bill,
>>>>>> You're right about the multiple frameworks argument, but that's not my >>>>>> goal, so I didn't factor it into my thought. To be honest, I'd be very >>>>>> interested in seeing someone actually reuse a set of ViewModel classes in >>>>>> WinForms, ASP.NET <http://asp.net/>, and WPF. I'd be happy enough >>>>>> just to see someone reuse them in WPF and SL. :)
>>>>>> Your point about "friction" between multiple Views raises a >>>>>> long-standing issue of mine. I think the terminology of MVVM is too >>>>>> limited. Really that pattern should be Model-ModelView-View-ViewModel >>>>>> (MMVVVM). The distiction between ModelView and ViewModel is the important >>>>>> point here. I've found that many times I create a VM for a model object, >>>>>> such as CustomerViewModel for Customer. I also create a ViewModel for a >>>>>> View object, such as CustomerViewModel for CustomerView. The friction you >>>>>> described is particular to the former case, where a "view model" is created >>>>>> for a model object, but not for one particular View. This is a sore point >>>>>> in the MVVM world.
>>>>>> I think that it is better to call a presentation-friendly wrapper >>>>>> around a Model object by its proper name: a ModelView. So, if I have a >>>>>> Customer class and want to make it easy to show an instance via binding in >>>>>> WPF, I should have a CustomerModelView class. If I have an input form that >>>>>> shows a new Customer, I should create an abstraction of that View, called >>>>>> CustomerViewModel. This way, the CustomerViewModel would perform the >>>>>> View-specific formatting, since it wouldn't be reused anywhere. However, >>>>>> the CustomerModelView could be shared across multiple Views and ViewModels.
>>>>>> Josh
>>>>>> On Mon, Dec 1, 2008 at 11:22 AM, Bill Kempf <weke...@gmail.com>wrote:
>>>>>>> Yes... and no. I think that if you're reaching for a value >>>>>>> converter, >>>>>>> you do need to stop and think, because it's often simpler, cleaner >>>>>>> and >>>>>>> easier to maintain to just use a special property on the view model. >>>>>>> However, there's reasons beyond the ones you've given to not go for a >>>>>>> special property.
>>>>>>> 1. If the value you need is unique to presentation, you should >>>>>>> consider still using a converter. Visibility is a classic example. >>>>>>> If one of your reasons to be using MVPoo is to be able to use >>>>>>> multiple >>>>>>> presentation frameworks (WPF, WinForms, WebForms, ASP.NET<http://asp.net/>MVC, etc.) >>>>>>> then the last thing you want to do is expose a property of type >>>>>>> Visibility. Even if you're sticking to WPF, there's two possible >>>>>>> "hidden" values with differing characteristics (hidden and >>>>>>> collapsed). >>>>>>> Choosing among these is a view concern, not a view model concern. >>>>>>> (It actually bugs me that the BooleanToVisibilityConverter doesn't >>>>>>> support this choice out of the box!)
>>>>>>> 2. Formatting is generally a presentation concern, and should be >>>>>>> handled by the view. It may be tempting to add a property that >>>>>>> formats that date in some specific way, but down the road when you >>>>>>> use >>>>>>> a different view that wants to format that date in another way, you >>>>>>> have friction between views that may not be easily resolved. Again, >>>>>>> if the conversion is to facilitate presentation, let the view handle >>>>>>> it.
>>>>>>> On Mon, Dec 1, 2008 at 11:08 AM, Josh Smith <flappleja...@gmail.com> >>>>>>> wrote: >>>>>>> > A ViewModel is basically a value converter on steroids. I takes >>>>>>> "raw" data >>>>>>> > and converts it into something presentation-friendly, and >>>>>>> vice-versa. If >>>>>>> > you ever find yourself binding an element's property to a >>>>>>> ViewModel's >>>>>>> > property, and you're using a value converter, stop! Why not just >>>>>>> create a >>>>>>> > property on the ViewModel that exposes the "formatted" data, and >>>>>>> then drop >>>>>>> > the value converter altogether?
>>>>>>> > The only place I can see a use for value converters in an MVVM >>>>>>> architecture >>>>>>> > is cross-element bindings. If I'm binding the Visibility of a >>>>>>> panel to the >>>>>>> > IsChecked of a CheckBox, then I will need to use the >>>>>>> > BooleanToVisibilityConverter. But, perhaps even in that case I >>>>>>> should take >>>>>>> > the "high road" and bind the IsChecked to a property on the >>>>>>> ViewModel, and >>>>>>> > then have a SomePanelVisibility property on the VM, to which the >>>>>>> Panel is >>>>>>> > bound.
>>>>>>> > Do you agree???
>>>>>>> -- >>>>>>> Quidquid latine dictum sit, altum sonatur. >>>>>>> - Whatever is said in Latin sounds profound.
>>>>>>> War is peace. Freedom is slavery. Bugs are features.
>>>>>>> On Mon, Dec 1, 2008 at 11:08 AM, Josh Smith <flappleja...@gmail.com> >>>>>>> wrote: >>>>>>> > A ViewModel is basically a value converter on steroids. I takes >>>>>>> "raw" data >>>>>>> > and converts it into something presentation-friendly, and >>>>>>> vice-versa. If >>>>>>> > you ever find yourself binding an element's property to a >>>>>>> ViewModel's >>>>>>> > property, and you're using a value converter, stop! Why not just >>>>>>> create a >>>>>>> > property on the ViewModel that exposes the "formatted" data, and >>>>>>> then drop >>>>>>> > the value converter altogether?
>>>>>>> > The only place I can see a use for value converters in an MVVM >>>>>>> architecture >>>>>>> > is cross-element bindings. If I'm binding the Visibility of a
On Mon, Dec 1, 2008 at 5:08 PM, Josh Smith <flappleja...@gmail.com> wrote: > A ViewModel is basically a value converter on steroids. I takes "raw" data > and converts it into something presentation-friendly, and vice-versa. If > you ever find yourself binding an element's property to a ViewModel's > property, and you're using a value converter, stop! Why not just create a > property on the ViewModel that exposes the "formatted" data, and then drop > the value converter altogether?
> The only place I can see a use for value converters in an MVVM architecture > is cross-element bindings. If I'm binding the Visibility of a panel to the > IsChecked of a CheckBox, then I will need to use the > BooleanToVisibilityConverter. But, perhaps even in that case I should take > the "high road" and bind the IsChecked to a property on the ViewModel, and > then have a SomePanelVisibility property on the VM, to which the Panel is > bound.
wow.. you all folks think (and email) faster than I can read : ) .... So I apologize for keeping the thread alive ( specially life cycle) if you had all moved on..
1) On avoiding ValueConverters when you have a ViewModel ... I agree with Bill ... Value Converters are OK for me (some times). Imo, ViewModel has logic and if it makes it readable to use Booleans instead of Visibility, I do it.. I try to keep ViewModel agnostic of presentation details like visibility, and ValueConverters does this nicely..
a. I am also a TypeDecriptorProvider virgin so I need to learn more about it...
2) On the "life cycle" of ViewModel (and Initialize method) ... I would love to better understand the decomposition of your lifecycle.. Does anyone have a hardcore rule?
a. When is the data fetched?
b. When are Commands wired and exposed??
c. Does the ViewModel wire up for Loaded ?? I kind of read on that.... Or Does the ViewModel implement an Interface that the view calls?? ( I opted for the latter the few times I did this, it is interface driven so generic) ..
d. Dispose () on a view model is new to me .... Never needed it before... what kind of scenarios need it??
My experience:
I hate thick constructors and I hate to delay Views... but a common gotcha for me is that if I wire up a DataContext to a form and it has not been fully initialized, then my Commands either do two or three times as much work (if I wire them after initialization) or can get into funny states where a command's CanExecute logic returns wrong result just because proper state was not ready...
If any one can share their practices on Initialize () of a ViewModel I would love to know more about the logical and consistent approach...
[Yes, the issues below have easy workarounds.... I am just trying to better read pros & cons to other's experiences :) ]. .
Thanks..
From: wpf-disciples@googlegroups.com [mailto:wpf-disciples@googlegroups.com] On Behalf Of Josh Smith Sent: Monday, December 01, 2008 9:47 AM To: wpf-disciples@googlegroups.com Subject: [WPF Disciples] Re: Thought: MVVM eliminates 99% of the need for ValueConverters
I'm not familiar with TypeDescriptor Providers, I will have to check that out. I agree that ideally you should refactor those "difficult" Model classes, but that's not always an option. Many times, especially in large companies, Model classes are inherited from other systems or the new system's predecessor, and cannot be modified.
Josh
On Mon, Dec 1, 2008 at 12:22 PM, Paul Stovell <stov...@gmail.com<mailto:stov...@gmail.com>> wrote:
As a general pattern, I'd say the ModelView is really just another part of the model - it just happens to be derived or adapting an existing object, but it may not always be. If you refactored it later to remove the messy Customer class, your ModelView might not make so much sense. In a similar situation, if my objects were based on DataRows in a legacy DataSet, I'd consider both the DS and the objects as part of the model. Perhaps just "CustomerAdapter"?
For a specific problem like that, for adapters, I always think of TypeDescriptor Providers. It would be trivial to build a very generic adapter to turn those methods into properties and exceptions into IDataErrorInfo, and you'd only code it once.
On Tue, Dec 2, 2008 at 3:41 AM, Josh Smith <flappleja...@gmail.com<mailto:flappleja...@gmail.com>> wrote: Sure thing.
Suppose the Customer class exposes each value as a getXYZ() method. The CustomerModelView (CMV) would then wrap each of them into a property. The CustomerViewModel (CMV) would be responsible for putting all the CMVs into an observable collection, provide aggregation values (i.e. total sales, etc) and CustomerView (CV) would be responsible for showing them all in a sexy WPF-ified way. :)
Suppose Customer has properties, not methods, but many of them store indici which can be used to retrieve values by look-up form other objects. The CMV would expose properties that internally perform the lookups.
Suppose Customer has validation logic that throws exceptions if a property is set to an invalid value. CMV would catch those exceptions and implement IDataErrorInfo to provide a soft, clean form of object validation.
In each of these situations, the ModelView (not the ViewModel) acts as a ViewModel-agnostic adapter around a Model object.
Josh
On Mon, Dec 1, 2008 at 12:04 PM, Paul Stovell <stov...@gmail.com<mailto:stov...@gmail.com>> wrote:
Hi Josh,
I'm interested in this scenario:
>> So, if I have a Customer class and want to make it easy to show an instance via binding in WPF, I should have a CustomerModelView class. If I have an input form that shows a new Customer, I should create an abstraction of that View, called CustomerViewModel. This way, the CustomerViewModel would perform the View-specific formatting, since it wouldn't be reused anywhere. However, the CustomerModelView could be shared across multiple Views and ViewModels.
Can you explain this in more detail? What kinds of properties/behavior/logic would you see on each class?
Perhaps we could have a "disciples code off" to see each person's approach.
Paul
On Tue, Dec 2, 2008 at 3:10 AM, Josh Smith <flappleja...@gmail.com<mailto:flappleja...@gmail.com>> wrote: Bill,
You're right about the multiple frameworks argument, but that's not my goal, so I didn't factor it into my thought. To be honest, I'd be very interested in seeing someone actually reuse a set of ViewModel classes in WinForms, ASP.NET<http://ASP.NET>, and WPF. I'd be happy enough just to see someone reuse them in WPF and SL. :)
Your point about "friction" between multiple Views raises a long-standing issue of mine. I think the terminology of MVVM is too limited. Really that pattern should be Model-ModelView-View-ViewModel (MMVVVM). The distiction between ModelView and ViewModel is the important point here. I've found that many times I create a VM for a model object, such as CustomerViewModel for Customer. I also create a ViewModel for a View object, such as CustomerViewModel for CustomerView. The friction you described is particular to the former case, where a "view model" is created for a model object, but not for one particular View. This is a sore point in the MVVM world.
I think that it is better to call a presentation-friendly wrapper around a Model object by its proper name: a ModelView. So, if I have a Customer class and want to make it easy to show an instance via binding in WPF, I should have a CustomerModelView class. If I have an input form that shows a new Customer, I should create an abstraction of that View, called CustomerViewModel. This way, the CustomerViewModel would perform the View-specific formatting, since it wouldn't be reused anywhere. However, the CustomerModelView could be shared across multiple Views and ViewModels.
Josh
On Mon, Dec 1, 2008 at 11:22 AM, Bill Kempf <weke...@gmail.com<mailto:weke...@gmail.com>> wrote:
Yes... and no. I think that if you're reaching for a value converter, you do need to stop and think, because it's often simpler, cleaner and easier to maintain to just use a special property on the view model. However, there's reasons beyond the ones you've given to not go for a special property.
1. If the value you need is unique to presentation, you should consider still using a converter. Visibility is a classic example. If one of your reasons to be using MVPoo is to be able to use multiple presentation frameworks (WPF, WinForms, WebForms, ASP.NET<http://ASP.NET> MVC, etc.) then the last thing you want to do is expose a property of type Visibility. Even if you're sticking to WPF, there's two possible "hidden" values with differing characteristics (hidden and collapsed). Choosing among these is a view concern, not a view model concern. (It actually bugs me that the BooleanToVisibilityConverter doesn't support this choice out of the box!)
2. Formatting is generally a presentation concern, and should be handled by the view. It may be tempting to add a property that formats that date in some specific way, but down the road when you use a different view that wants to format that date in another way, you have friction between views that may not be easily resolved. Again, if the conversion is to facilitate presentation, let the view handle it.
On Mon, Dec 1, 2008 at 11:08 AM, Josh Smith <flappleja...@gmail.com<mailto:flappleja...@gmail.com>> wrote:
> A ViewModel is basically a value converter on steroids. I takes "raw" data > and converts it into something presentation-friendly, and vice-versa. If > you ever find yourself binding an element's property to a ViewModel's > property, and you're using a value converter, stop! Why not just create a > property on the ViewModel that exposes the "formatted" data, and then drop > the value converter altogether?
> The only place I can see a use for value converters in an MVVM architecture > is cross-element bindings. If I'm binding the Visibility of a panel to the > IsChecked of a CheckBox, then I will need to use the > BooleanToVisibilityConverter. But, perhaps even in that case I should take > the "high road" and bind the IsChecked to a property on the ViewModel, and > then have a SomePanelVisibility property on the VM, to which the Panel is > bound.
> Do you agree???
-- Quidquid latine dictum sit, altum sonatur. - Whatever is said in Latin sounds profound.
War is peace. Freedom is slavery. Bugs are features.
On Mon, Dec 1, 2008 at 11:08 AM, Josh Smith <flappleja...@gmail.com<mailto:flappleja...@gmail.com>> wrote:
> A ViewModel is basically a value converter on steroids. I takes "raw" data > and converts it into something presentation-friendly, and vice-versa. If > you ever find yourself binding an element's property to a ViewModel's > property, and you're using a value converter, stop! Why not just create a
I have no hard-and-fast rule for this. Usually, data should be fetched when it's needed, unless you're talking about a huge amount of static data that might need to be pre-loaded and cached. Karl raised a good point the other day during one of our marathon phone calls that in a multi-user system, data should be retrieved delayed and performed as frequently as possible because a record could become stale while sitting on the client.
>> b. When are Commands wired and exposed??
In my book, commands are exposed by ViewModel objects as properties. They are wired to command sources (i.e. Buttons) via data binding when a View is loaded.
>> c. Does the ViewModel wire up for Loaded ?? I kind of read on
that…. Or Does the ViewModel implement an Interface that the view calls?? ( I opted for the latter the few times I did this, it is interface driven so generic) ..
In my book, no way. My Views are created via the magic of typed datatemplate resolution, in response to a ViewModel object trying to be "shown" in the UI. My VM objects have their Initialize method invoked at the time that they are put into the UI...which means when they are added to the "live" VM object graph.
>> d. Dispose () on a view model is new to me …. Never needed it
before… what kind of scenarios need it??
Profile your MVVM apps and you might find you have some memory leaks. I sure did. The problem was that my VM objects were hooking events on objects that live longer than they do, but never unhooking the event. I have a Dispose method on my VM base class, so that subclasses can override a virtual OnDispose() and unhook the handlers, to ensure proper garbage collection.
Josh
On Mon, Dec 1, 2008 at 2:41 PM, Jaime Rodriguez <jai...@microsoft.com>wrote:
> wow.. you all folks think (and email) faster than I can read : ) …. > So I apologize for keeping the thread alive ( specially life cycle) if you > had all moved on..
> 1) On avoiding ValueConverters when you have a ViewModel … I agree > with Bill … Value Converters are OK for me (some times). Imo, ViewModel > has logic and if it makes it readable to use Booleans instead of > Visibility, I do it.. I try to keep ViewModel agnostic of presentation > details like visibility, and ValueConverters does this nicely..
> a. I am also a TypeDecriptorProvider virgin so I need to learn more > about it…
> 2) On the "life cycle" of ViewModel (and Initialize method) … I > would love to better understand the decomposition of your lifecycle.. Does > anyone have a hardcore rule?
> a. When is the data fetched?
> b. When are Commands wired and exposed??
> c. Does the ViewModel wire up for Loaded ?? I kind of read on > that…. Or Does the ViewModel implement an Interface that the view > calls?? ( I opted for the latter the few times I did this, it is > interface driven so generic) ..
> d. Dispose () on a view model is new to me …. Never needed it > before… what kind of scenarios need it??
> My experience:
> I hate thick constructors and I hate to delay Views… but a common gotcha > for me is that if I wire up a DataContext to a form and it has not been > fully initialized, then my Commands either do two or three times as much > work (if I wire them after initialization) or can get into funny states > where a command's CanExecute logic returns wrong result just because proper > state was not ready…
> If any one can share their practices on Initialize () of a ViewModel I > would love to know more about the logical and consistent approach…
> [Yes, the issues below have easy workarounds…. > I am just trying to better read pros & cons to other's experiences J ]. > .
> Thanks..
> *From:* wpf-disciples@googlegroups.com [mailto: > wpf-disciples@googlegroups.com] *On Behalf Of *Josh Smith > *Sent:* Monday, December 01, 2008 9:47 AM > *To:* wpf-disciples@googlegroups.com > *Subject:* [WPF Disciples] Re: Thought: MVVM eliminates 99% of the need > for ValueConverters
> I'm not familiar with TypeDescriptor Providers, I will have to check that > out. I agree that ideally you should refactor those "difficult" Model > classes, but that's not always an option. Many times, especially in large > companies, Model classes are inherited from other systems or the new > system's predecessor, and cannot be modified.
> Josh
> On Mon, Dec 1, 2008 at 12:22 PM, Paul Stovell <stov...@gmail.com> wrote:
> As a general pattern, I'd say the ModelView is really just another part of > the model - it just happens to be derived or adapting an existing object, > but it may not always be. If you refactored it later to remove the messy > Customer class, your ModelView might not make so much sense. In a similar > situation, if my objects were based on DataRows in a legacy DataSet, I'd > consider both the DS and the objects as part of the model. Perhaps just > "CustomerAdapter"?
> For a specific problem like that, for adapters, I always think of > TypeDescriptor Providers. It would be trivial to build a very generic > adapter to turn those methods into properties and exceptions into > IDataErrorInfo, and you'd only code it once.
> On Tue, Dec 2, 2008 at 3:41 AM, Josh Smith <flappleja...@gmail.com> > wrote:
> Sure thing.
> Suppose the Customer class exposes each value as a getXYZ() method. The > CustomerModelView (CMV) would then wrap each of them into a property. The > CustomerViewModel (CMV) would be responsible for putting all the CMVs into > an observable collection, provide aggregation values (i.e. total sales, etc) > and CustomerView (CV) would be responsible for showing them all in a sexy > WPF-ified way. :)
> Suppose Customer has properties, not methods, but many of them store indici > which can be used to retrieve values by look-up form other objects. The CMV > would expose properties that internally perform the lookups.
> Suppose Customer has validation logic that throws exceptions if a property > is set to an invalid value. CMV would catch those exceptions and implement > IDataErrorInfo to provide a soft, clean form of object validation.
> In each of these situations, the ModelView (not the ViewModel) acts as a > ViewModel-agnostic adapter around a Model object.
> Josh
> On Mon, Dec 1, 2008 at 12:04 PM, Paul Stovell <stov...@gmail.com> wrote:
> Hi Josh,
> I'm interested in this scenario:
> >> So, if I have a Customer class and want to make it easy to show an > instance via binding in WPF, I should have a CustomerModelView class. If I > have an input form that shows a new Customer, I should create an abstraction > of that View, called CustomerViewModel. This way, the CustomerViewModel > would perform the View-specific formatting, since it wouldn't be reused > anywhere. However, the CustomerModelView could be shared across multiple > Views and ViewModels.
> Can you explain this in more detail? What kinds of > properties/behavior/logic would you see on each class?
> Perhaps we could have a "disciples code off" to see each person's approach.
> Paul
> On Tue, Dec 2, 2008 at 3:10 AM, Josh Smith <flappleja...@gmail.com> > wrote:
> Bill,
> You're right about the multiple frameworks argument, but that's not my > goal, so I didn't factor it into my thought. To be honest, I'd be very > interested in seeing someone actually reuse a set of ViewModel classes in > WinForms, ASP.NET, and WPF. I'd be happy enough just to see someone reuse > them in WPF and SL. :)
> Your point about "friction" between multiple Views raises a long-standing > issue of mine. I think the terminology of MVVM is too limited. Really that > pattern should be Model-ModelView-View-ViewModel (MMVVVM). The distiction > between ModelView and ViewModel is the important point here. I've found > that many times I create a VM for a model object, such as CustomerViewModel > for Customer. I also create a ViewModel for a View object, such as > CustomerViewModel for CustomerView. The friction you described is > particular to the former case, where a "view model" is created for a model > object, but not for one particular View. This is a sore point in the MVVM > world.
> I think that it is better to call a presentation-friendly wrapper around a > Model object by its proper name: a ModelView. So, if I have a Customer > class and want to make it easy to show an instance via binding in WPF, I > should have a CustomerModelView class. If I have an input form that shows a > new Customer, I should create an abstraction of that View, called > CustomerViewModel. This way, the CustomerViewModel would perform the > View-specific formatting, since it wouldn't be reused anywhere. However, > the CustomerModelView could be shared across multiple Views and ViewModels.
> Josh
> On Mon, Dec 1, 2008 at 11:22 AM, Bill Kempf <weke...@gmail.com> wrote:
> Yes... and no. I think that if you're reaching for a value converter, > you do need to stop and think, because it's often simpler, cleaner and > easier to maintain to just use a special property on the view model. > However, there's reasons beyond the ones you've given to not go for a > special property.
> 1. If the value you need is unique to presentation, you should > consider still using a converter. Visibility is a classic example. > If one of your reasons to be using MVPoo is to be able to use multiple > presentation frameworks (WPF, WinForms, WebForms, ASP.NET MVC, etc.) > then the last thing you want to do is expose a property of type > Visibility. Even if you're sticking to WPF, there's two possible > "hidden" values with differing characteristics (hidden and collapsed). > Choosing among these is a view concern, not a view model
I’m with Marlon on this, while I agree that the VM can eliminate all converters I don’t like the idea of having a ViewModel too tied to the view and, after all, converters are very reusable J.
Just had a look at Silverlight validation model, think there’s a lot of work to do to fit it in a M-V-VM environment…
-Corrado
From: wpf-disciples@googlegroups.com [mailto:wpf-disciples@googlegroups.com] On Behalf Of Marlon Grech Sent: lunedì 1 dicembre 2008 20:16 To: wpf-disciples@googlegroups.com Subject: [WPF Disciples] Re: Thought: MVVM eliminates 99% of the need for ValueConverters
I also think that this should be 50% 50%... If there is something strongly UI coupled then I would probably put it in a ValueConverter...
yet I must say I hate those creatures so called IValueConverters :/
On Mon, Dec 1, 2008 at 5:08 PM, Josh Smith <flappleja...@gmail.com> wrote:
A ViewModel is basically a value converter on steroids. I takes "raw" data and converts it into something presentation-friendly, and vice-versa. If you ever find yourself binding an element's property to a ViewModel's property, and you're using a value converter, stop! Why not just create a property on the ViewModel that exposes the "formatted" data, and then drop the value converter altogether?
The only place I can see a use for value converters in an MVVM architecture is cross-element bindings. If I'm binding the Visibility of a panel to the IsChecked of a CheckBox, then I will need to use the BooleanToVisibilityConverter. But, perhaps even in that case I should take the "high road" and bind the IsChecked to a property on the ViewModel, and then have a SomePanelVisibility property on the VM, to which the Panel is bound.
Suppose you're working in the designer-developer workflow. Should the designers have to write the value converters? What if they don't know how to write some of them? I think it's easier to have the VM expose the properties that they need to bind against, instead of having the designers ask the developers to write a bunch of one-off converters for them.
At the end of the day, MVVM (like any other pattern) is a set of guidelines, not rules. So, as long as using the pattern makes your application better, development easier, and testing more thorough, it's all good.
Josh
On Mon, Dec 1, 2008 at 2:54 PM, Corrado Cavalli <corradocava...@gmail.com>wrote:
> I'm with Marlon on this, while I agree that the VM can eliminate all > converters I don't like the idea of having a ViewModel too tied to the view > and, after all, converters are very reusable J.
> Just had a look at Silverlight validation model, think there's a lot of > work to do to fit it in a M-V-VM environment…
> -Corrado
> *From:* wpf-disciples@googlegroups.com [mailto: > wpf-disciples@googlegroups.com] *On Behalf Of *Marlon Grech > *Sent:* lunedì 1 dicembre 2008 20:16 > *To:* wpf-disciples@googlegroups.com > *Subject:* [WPF Disciples] Re: Thought: MVVM eliminates 99% of the need > for ValueConverters
> I also think that this should be 50% 50%... If there is something strongly > UI coupled then I would probably put it in a ValueConverter...
> yet I must say I hate those creatures so called IValueConverters :/
> On Mon, Dec 1, 2008 at 5:08 PM, Josh Smith <flappleja...@gmail.com> > wrote:
> A ViewModel is basically a value converter on steroids. I takes "raw" data > and converts it into something presentation-friendly, and vice-versa. If > you ever find yourself binding an element's property to a ViewModel's > property, and you're using a value converter, stop! Why not just create a > property on the ViewModel that exposes the "formatted" data, and then drop > the value converter altogether?
> The only place I can see a use for value converters in an MVVM architecture > is cross-element bindings. If I'm binding the Visibility of a panel to the > IsChecked of a CheckBox, then I will need to use the > BooleanToVisibilityConverter. But, perhaps even in that case I should take > the "high road" and bind the IsChecked to a property on the ViewModel, and > then have a SomePanelVisibility property on the VM, to which the Panel is > bound.
If it's a "one-off" converter, it's probably better done in the VM. However, most of the time you'll find you can reuse converters. I most certainly would not expect the designer to code one, regardless of whether or not we convert in the VM or in a VC.
On Mon, Dec 1, 2008 at 3:02 PM, Josh Smith <flappleja...@gmail.com> wrote: > Suppose you're working in the designer-developer workflow. Should the > designers have to write the value converters? What if they don't know how > to write some of them? I think it's easier to have the VM expose the > properties that they need to bind against, instead of having the designers > ask the developers to write a bunch of one-off converters for them.
> At the end of the day, MVVM (like any other pattern) is a set of guidelines, > not rules. So, as long as using the pattern makes your application better, > development easier, and testing more thorough, it's all good.
> Josh
> On Mon, Dec 1, 2008 at 2:54 PM, Corrado Cavalli <corradocava...@gmail.com> > wrote:
>> I'm with Marlon on this, while I agree that the VM can eliminate all >> converters I don't like the idea of having a ViewModel too tied to the view >> and, after all, converters are very reusable J.
>> Just had a look at Silverlight validation model, think there's a lot of >> work to do to fit it in a M-V-VM environment…
>> -Corrado
>> From: wpf-disciples@googlegroups.com >> [mailto:wpf-disciples@googlegroups.com] On Behalf Of Marlon Grech >> Sent: lunedì 1 dicembre 2008 20:16
>> To: wpf-disciples@googlegroups.com >> Subject: [WPF Disciples] Re: Thought: MVVM eliminates 99% of the need for >> ValueConverters
>> I also think that this should be 50% 50%... If there is something strongly >> UI coupled then I would probably put it in a ValueConverter...
>> yet I must say I hate those creatures so called IValueConverters :/
>> On Mon, Dec 1, 2008 at 5:08 PM, Josh Smith <flappleja...@gmail.com> wrote:
>> A ViewModel is basically a value converter on steroids. I takes "raw" >> data and converts it into something presentation-friendly, and vice-versa. >> If you ever find yourself binding an element's property to a ViewModel's >> property, and you're using a value converter, stop! Why not just create a >> property on the ViewModel that exposes the "formatted" data, and then drop >> the value converter altogether?
>> The only place I can see a use for value converters in an MVVM >> architecture is cross-element bindings. If I'm binding the Visibility of a >> panel to the IsChecked of a CheckBox, then I will need to use the >> BooleanToVisibilityConverter. But, perhaps even in that case I should take >> the "high road" and bind the IsChecked to a property on the ViewModel, and >> then have a SomePanelVisibility property on the VM, to which the Panel is >> bound.
>> Do you agree???
-- Quidquid latine dictum sit, altum sonatur. - Whatever is said in Latin sounds profound.
War is peace. Freedom is slavery. Bugs are features.
Yes, patterns are guidelines more than rules. I followed that discussion with very much interest and can’t wait to try some of that in my next app, and it’s really interesting to see the different streams of thoughts. So far I think I see two major variations in the exposed practices, one which considers that VM is a kind of replacement for code-behind (let’s call it a top-down approach) and thus a VM is very tightly bound to a View. The other is rather a bottom-up approach and puts the VM as an extension of the model, but formatted for the View.
In the project I worked last, we took a very pragmatic approach, and used VM for various reasons, the most important being avoiding that our designers have to write any code. Josh’s point is really valid, designers should not have to worry about code, period. It’s not their job. My role as an integrator (IM calls that “Interactive Developer”) was to specifically avoid designers to have that kind of problems. This results in a series of roundtrips between developers and designers coordinated by the integrator. In that sense, a well thought VM can avoid a number of roundtrips. To me, this is the most important aspect of the VM, because every roundtrip costs a lot of money, and designers are damn expensive in a project.
When I say we were pragmatic, I mean that because some in the team were quite unexperienced, we ended up having quite some code in the code-behind. If I had to do it again today, I would probably be stricter about that. But on the other hand, I saw another team take a much stricter approach (Josh: That was Linus’ team, you probably remember him from our memorable dinner in NY) and they spent a lot more time on some details than we did. Also, some of the development was done in India, and their strict approach cost quite a lot of time round tripping between India and Switzerland, or worse, having to refactor much of the code that the Indian team delivered.
Anyway… my next project should be a much smaller one (Silverlight), and I want to apply MVVM in a stricter way there. That should be interesting J
From: wpf-disciples@googlegroups.com [mailto:wpf-disciples@googlegroups.com] On Behalf Of Josh Smith Sent: Monday, December 01, 2008 9:03 PM To: wpf-disciples@googlegroups.com Subject: [WPF Disciples] Re: Thought: MVVM eliminates 99% of the need for ValueConverters
Suppose you're working in the designer-developer workflow. Should the designers have to write the value converters? What if they don't know how to write some of them? I think it's easier to have the VM expose the properties that they need to bind against, instead of having the designers ask the developers to write a bunch of one-off converters for them.
At the end of the day, MVVM (like any other pattern) is a set of guidelines, not rules. So, as long as using the pattern makes your application better, development easier, and testing more thorough, it's all good.
Josh
On Mon, Dec 1, 2008 at 2:54 PM, Corrado Cavalli <corradocava...@gmail.com> wrote:
I'm with Marlon on this, while I agree that the VM can eliminate all converters I don't like the idea of having a ViewModel too tied to the view and, after all, converters are very reusable J.
Just had a look at Silverlight validation model, think there's a lot of work to do to fit it in a M-V-VM environment…
-Corrado
From: wpf-disciples@googlegroups.com [mailto:wpf-disciples@googlegroups.com] On Behalf Of Marlon Grech Sent: lunedì 1 dicembre 2008 20:16
To: wpf-disciples@googlegroups.com Subject: [WPF Disciples] Re: Thought: MVVM eliminates 99% of the need for ValueConverters
I also think that this should be 50% 50%... If there is something strongly UI coupled then I would probably put it in a ValueConverter...
yet I must say I hate those creatures so called IValueConverters :/
On Mon, Dec 1, 2008 at 5:08 PM, Josh Smith <flappleja...@gmail.com> wrote:
A ViewModel is basically a value converter on steroids. I takes "raw" data and converts it into something presentation-friendly, and vice-versa. If you ever find yourself binding an element's property to a ViewModel's property, and you're using a value converter, stop! Why not just create a property on the ViewModel that exposes the "formatted" data, and then drop the value converter altogether?
The only place I can see a use for value converters in an MVVM architecture is cross-element bindings. If I'm binding the Visibility of a panel to the IsChecked of a CheckBox, then I will need to use the BooleanToVisibilityConverter. But, perhaps even in that case I should take the "high road" and bind the IsChecked to a property on the ViewModel, and then have a SomePanelVisibility property on the VM, to which the Panel is bound.
Interesting, but by that description I don't fall into either camp. My goals are to 1) eliminate as much need for the code behind as possible, so that designers don't ever write code, and 2) make unit testing almost entirely possible with out any sort of UI automation. However, I want to couple my VM as loosely as possible to the V. I prefer converters in any scenario that has to do with conversions that are coupled to the view.
On Mon, Dec 1, 2008 at 3:31 PM, Laurent Bugnion, GalaSoft [MVP]
<laur...@galasoft.ch> wrote: > I want to chime in on that one.
> Yes, patterns are guidelines more than rules. I followed that discussion > with very much interest and can't wait to try some of that in my next app, > and it's really interesting to see the different streams of thoughts. So far > I think I see two major variations in the exposed practices, one which > considers that VM is a kind of replacement for code-behind (let's call it a > top-down approach) and thus a VM is very tightly bound to a View. The other > is rather a bottom-up approach and puts the VM as an extension of the model, > but formatted for the View.
> In the project I worked last, we took a very pragmatic approach, and used VM > for various reasons, the most important being avoiding that our designers > have to write any code. Josh's point is really valid, designers should not > have to worry about code, period. It's not their job. My role as an > integrator (IM calls that "Interactive Developer") was to specifically avoid > designers to have that kind of problems. This results in a series of > roundtrips between developers and designers coordinated by the integrator. > In that sense, a well thought VM can avoid a number of roundtrips. To me, > this is the most important aspect of the VM, because every roundtrip costs a > lot of money, and designers are damn expensive in a project.
> When I say we were pragmatic, I mean that because some in the team were > quite unexperienced, we ended up having quite some code in the code-behind. > If I had to do it again today, I would probably be stricter about that. But > on the other hand, I saw another team take a much stricter approach (Josh: > That was Linus' team, you probably remember him from our memorable dinner in > NY) and they spent a lot more time on some details than we did. Also, some > of the development was done in India, and their strict approach cost quite a > lot of time round tripping between India and Switzerland, or worse, having > to refactor much of the code that the Indian team delivered.
> Anyway… my next project should be a much smaller one (Silverlight), and I > want to apply MVVM in a stricter way there. That should be interesting J
> From: wpf-disciples@googlegroups.com [mailto:wpf-disciples@googlegroups.com] > On Behalf Of Josh Smith > Sent: Monday, December 01, 2008 9:03 PM
> To: wpf-disciples@googlegroups.com > Subject: [WPF Disciples] Re: Thought: MVVM eliminates 99% of the need for > ValueConverters
> Suppose you're working in the designer-developer workflow. Should the > designers have to write the value converters? What if they don't know how > to write some of them? I think it's easier to have the VM expose the > properties that they need to bind against, instead of having the designers > ask the developers to write a bunch of one-off converters for them.
> At the end of the day, MVVM (like any other pattern) is a set of guidelines, > not rules. So, as long as using the pattern makes your application better, > development easier, and testing more thorough, it's all good.
> Josh
> On Mon, Dec 1, 2008 at 2:54 PM, Corrado Cavalli <corradocava...@gmail.com> > wrote:
> I'm with Marlon on this, while I agree that the VM can eliminate all > converters I don't like the idea of having a ViewModel too tied to the view > and, after all, converters are very reusable J.
> Just had a look at Silverlight validation model, think there's a lot of work > to do to fit it in a M-V-VM environment…
> -Corrado
> From: wpf-disciples@googlegroups.com [mailto:wpf-disciples@googlegroups.com] > On Behalf Of Marlon Grech > Sent: lunedì 1 dicembre 2008 20:16
> To: wpf-disciples@googlegroups.com > Subject: [WPF Disciples] Re: Thought: MVVM eliminates 99% of the need for > ValueConverters
> I also think that this should be 50% 50%... If there is something strongly > UI coupled then I would probably put it in a ValueConverter...
> yet I must say I hate those creatures so called IValueConverters :/
> On Mon, Dec 1, 2008 at 5:08 PM, Josh Smith <flappleja...@gmail.com> wrote:
> A ViewModel is basically a value converter on steroids. I takes "raw" data > and converts it into something presentation-friendly, and vice-versa. If > you ever find yourself binding an element's property to a ViewModel's > property, and you're using a value converter, stop! Why not just create a > property on the ViewModel that exposes the "formatted" data, and then drop > the value converter altogether?
> The only place I can see a use for value converters in an MVVM architecture > is cross-element bindings. If I'm binding the Visibility of a panel to the > IsChecked of a CheckBox, then I will need to use the > BooleanToVisibilityConverter. But, perhaps even in that case I should take > the "high road" and bind the IsChecked to a property on the ViewModel, and > then have a SomePanelVisibility property on the VM, to which the Panel is > bound.
> Do you agree???
-- Quidquid latine dictum sit, altum sonatur. - Whatever is said in Latin sounds profound.
War is peace. Freedom is slavery. Bugs are features.
Great feedback, Laurent. Looking forward to your upcoming blog post about your experience with taking other approaches. ;)
I sense that I'm the odd man out in this discussion. I'm very curious to know what concrete advantages others have gained by treating the VM as something clearly distinct and separate from the View. What do you really gain from using value converters and code-behind logic, as opposed to putting that stuff into the VM? I'm not opposed to that approach, it's just not how I've done MVVM so far. While working on Crack.NET I created very dumb, passive Views and smart, demanding ViewModels. I know that the good Doctor is quite versed in MVVM, and has reviewed the Crack code, so I'd love to hear his thoughts on this.
josh
On Mon, Dec 1, 2008 at 3:31 PM, Laurent Bugnion, GalaSoft [MVP]
<laur...@galasoft.ch> wrote: > I want to chime in on that one.
> Yes, patterns are guidelines more than rules. I followed that discussion > with very much interest and can't wait to try some of that in my next app, > and it's really interesting to see the different streams of thoughts. So far > I think I see two major variations in the exposed practices, one which > considers that VM is a kind of replacement for code-behind (let's call it a > top-down approach) and thus a VM is very tightly bound to a View. The other > is rather a bottom-up approach and puts the VM as an extension of the model, > but formatted for the View.
> In the project I worked last, we took a very pragmatic approach, and used > VM for various reasons, the most important being avoiding that our designers > have to write any code. Josh's point is really valid, designers should not > have to worry about code, period. It's not their job. My role as an > integrator (IM calls that "Interactive Developer") was to specifically avoid > designers to have that kind of problems. This results in a series of > roundtrips between developers and designers coordinated by the integrator. > In that sense, a well thought VM can avoid a number of roundtrips. To me, > this is the most important aspect of the VM, because every roundtrip costs a > lot of money, and designers are damn expensive in a project.
> When I say we were pragmatic, I mean that because some in the team were > quite unexperienced, we ended up having quite some code in the code-behind. > If I had to do it again today, I would probably be stricter about that. But > on the other hand, I saw another team take a much stricter approach (Josh: > That was Linus' team, you probably remember him from our memorable dinner in > NY) and they spent a lot more time on some details than we did. Also, some > of the development was done in India, and their strict approach cost quite a > lot of time round tripping between India and Switzerland, or worse, having > to refactor much of the code that the Indian team delivered.
> Anyway… my next project should be a much smaller one (Silverlight), and I > want to apply MVVM in a stricter way there. That should be interesting J
> *From:* wpf-disciples@googlegroups.com [mailto: > wpf-disciples@googlegroups.com] *On Behalf Of *Josh Smith > *Sent:* Monday, December 01, 2008 9:03 PM > *To:* wpf-disciples@googlegroups.com > *Subject:* [WPF Disciples] Re: Thought: MVVM eliminates 99% of the need > for ValueConverters
> Suppose you're working in the designer-developer workflow. Should the > designers have to write the value converters? What if they don't know how > to write some of them? I think it's easier to have the VM expose the > properties that they need to bind against, instead of having the designers > ask the developers to write a bunch of one-off converters for them.
> At the end of the day, MVVM (like any other pattern) is a set of > guidelines, not rules. So, as long as using the pattern makes your > application better, development easier, and testing more thorough, it's all > good.
> Josh
> On Mon, Dec 1, 2008 at 2:54 PM, Corrado Cavalli <corradocava...@gmail.com> > wrote:
> I'm with Marlon on this, while I agree that the VM can eliminate all > converters I don't like the idea of having a ViewModel too tied to the view > and, after all, converters are very reusable J.
> Just had a look at Silverlight validation model, think there's a lot of > work to do to fit it in a M-V-VM environment…
> -Corrado
> *From:* wpf-disciples@googlegroups.com [mailto: > wpf-disciples@googlegroups.com] *On Behalf Of *Marlon Grech > *Sent:* lunedì 1 dicembre 2008 20:16
> *To:* wpf-disciples@googlegroups.com > *Subject:* [WPF Disciples] Re: Thought: MVVM eliminates 99% of the need > for ValueConverters
> I also think that this should be 50% 50%... If there is something strongly > UI coupled then I would probably put it in a ValueConverter...
> yet I must say I hate those creatures so called IValueConverters :/
> On Mon, Dec 1, 2008 at 5:08 PM, Josh Smith <flappleja...@gmail.com> > wrote:
> A ViewModel is basically a value converter on steroids. I takes "raw" data > and converts it into something presentation-friendly, and vice-versa. If > you ever find yourself binding an element's property to a ViewModel's > property, and you're using a value converter, stop! Why not just create a > property on the ViewModel that exposes the "formatted" data, and then drop > the value converter altogether?
> The only place I can see a use for value converters in an MVVM architecture > is cross-element bindings. If I'm binding the Visibility of a panel to the > IsChecked of a CheckBox, then I will need to use the > BooleanToVisibilityConverter. But, perhaps even in that case I should take > the "high road" and bind the IsChecked to a property on the ViewModel, and > then have a SomePanelVisibility property on the VM, to which the Panel is > bound.