I think it depends on who is responsible for printing. Probably not the business object, and thus probably not the CslaDataProvider.
Microsoft has been talking up this ViewModel pattern (Model/View/ViewModel and maybe Controller) idea. The gist of it is that WPF commanding is great, but needs a target. The target shouldn't be the view or the controller or the model, so they invented the ViewModel.
The ViewModel is part of the UI, and basically provides a way to get at the Model, and a way to expose methods for commanding.
In a sense, the CslaDataProvider is a ViewModel - just one that exposes a very defined set of methods for commanding. But conceptually, a ViewModel does exactly what CslaDataProvider does - grants access to the Model (the business object) and supports various commands for the UI.
I have just one quibble with the ViewModel idea: I think the ViewModel is likely to gather business logic, even though it is part of the UI. It is just too darn convenient as a location to do validation-before-save and that sort of thing - so it may lead to really fancy/complex VB3 style coding.
But I guess that's true of anything we come up with - it can be misused...
Anyway, in general terms, you can probably combine the concepts. Use a CslaDataProvider to do the basic CRUD operations, because it supports those. And create a ViewModel or CommandProcessor object to which you can bind your other buttons.
If you have a controller, the controller is really responsible for most of what CslaDataProvider does - you just write the code yourself instead of using a pre-built component. And in that case the ViewModel pattern probably makes more sense overall, and you may just implement all the data provider operations in your controller code.
But if you manage everything purely through XAML, then you may not have a discrete controller. In that case having a data provider plus a command processor may be a better alternative. This is the angle I've been exploring.
In your resources then, you'd have two things:
<..Resources>
<csla:CslaDataProvider x:Key="MyData" ... />
<this:PrintHandler x:Key="PrintHandler"
DataContext="{StaticResource MyData}" />
</..Resources>
And then your Print button can use the PrintHandler as a target.
The thing is, nearly any .NET object (with a public default constructor) can be used as a resource like this. It doesn't need anything special really. Though to be a command target the object does need to inherit from UIElement (which is the whole reason CslaDataProviderCommandManager exists).
So your PrintHandler class would just inherit from UIElement and would include the code necessary to implement the Print command - much like CslaDataProviderCommandManager does with its commands.
The DataContext (or you can use the Source model I've been doing for Silverlight) allows PrintHandler to gain access to the business object you want to print.
If you look at the way I use Csla.Wpf.ObjectContext in the 2008 book, you'll see that I use it in a manner very similar to what I'm talking about here. It doesn't support any commands, but does expose a bunch of bindable properties based on the state of the business object.
It isn’t difficult really :)
The thing is, that some bit of code has to handle the command.
Commanding is only magical at the XAML level, but behind the scenes there’s
always a command hander that does some actual work.
Btw, you can create your own commands too – you aren’t
limited to just those defined by the standard list.
Rocky
RockfordLhotka:Microsoft has been talking up this ViewModel pattern (Model/View/ViewModel and maybe Controller) idea. The gist of it is that WPF commanding is great, but needs a target. The target shouldn't be the view or the controller or the model, so they invented the ViewModel.
The ViewModel is part of the UI, and basically provides a way to get at the Model, and a way to expose methods for commanding.
I will admit that I'm still a WPF newbie, not to mention the whole MVC/MVVM concept. And this certainly isn't a CSLA-specific question. But I'm curious - why would the Controller not be a good target for a WPF command? Isn't the point of WPF commands to provide a way for multiple UI elements to fire off the same code? Since the Controller is designed to handle the user interaction with the view... why wouldn't you target a WPF command at your Controller? Why the need for a ViewModel?
- Scott
I don’t know that I can do justice to the MVVM pattern,
you should really read the content put out by its proponents.
My understanding is that the Controller should be UI-neutral.
There’s still this (imo mythical) thought that you can create a
Controller that works for Windows, web, WPF and other interface types, so the
controller shouldn’t be specific to any UI technology.
I think that’s unrealistic, because the typical user
experience and UI flow for a smart client and a web client are quite different.
Maybe, just maybe, you could share a Controller between a WinForms and WPF and
Silverlight UI, but the web is so different they just don’t line up.
Anyway, I suspect that’s the rationalization – keep the
Controller independent of the specific UI technology – which means it
couldn’t be a command target, because then it would have to inherit from
UIElement and would be tied directly to WPF.
Putting my skepticism aside just a bit – I think you
really could envision a Controller that supported both WPF and Silverlight UIs,
because they are nearly the same. But the implementation isn’t the
same at the moment, so it would be bad to tie the Controller directly to WPF or
Silverlight even in this case.
The ViewModel provides a layer of abstraction between the View
and the Controller (and the Model) that can be safely UI specific. At least
that’s my understanding.
Rocky
RockfordLhotka:I don’t know that I can do justice to the MVVM pattern, you should really read the content put out by its proponents.
Great - more reading to add to my list. And since MVVM seems to be the "it" way of building WPF apps, I suppose I can't dodge this one... *sigh*
This is getting a little far afield of Andy's original question, but I wanted to comment that I agree that building the "uber-Controller" to handle any and all UI comers is a pipe dream. If you could do that, then you wouldn't have different UI constructs - because they'd all work the same. At that point, it's just transport differences.
Just MHO. Thanks.
- Scott
Copyright (c) Marimer LLC