.
Hello guys,
Consider the usual scenario of Prism (WPF/Silverlight) in which we've multiple regions, and in each goes a view (XAML), so a situation might arise when we interact with one view (XAML), either using mouse, or keyboard, we may want to change or update other views (which happen to be different XAMLs) accordingly. For example, on selecting an item from a view, say ItemPanelView, we may want to show the details of the selected item in other view, say ItemDetailsView.
So my question is,
Would it be a good idea to bind elements from one view (XAML), to the elements in the other views (different XAMLs), to implement such functionalities? If I'm not wrong, using this approach we would not need to go from one presenter to other (using TwoWay bindings etc), so as to update the view in other region.
Or, is there any elegant yet simple way to do this?
.
I suggest you take a look at the Prism's EventAggregator (http://blogs.msdn.com/b/francischeung/archive/2008/06/02/decoupled-communication-with-prism-event-aggregation.aspx). Each of your views (or preferably view models to which views can respond/update using triggers) can subscribe to / publish a shared event. However, I suggest that instead of simply responding to a mouse click or keyboard event to raise this shared event, make the shared event meaningful (i.e. MyItemSelected or MyItemHidden). If you need more assistance or clarification with this, let me know.
There are several ways to do that without breaking canonical concept of the PRiSM.
As [MSDN docs][1] (Chapter 9: Communicating Between Loosely Coupled Components) tell us:
When communicating between modules, it is important that you know the differences between the approaches so that you can best determine which approach to use in your particular scenario. The Prism Library provides the following communication approaches:
Commanding. Use when there is an expectation of immediate action from the user interaction.
Event aggregation. For communication across view models, presenters, or controllers when there is not a direct action-reaction expectation.
Region context. Use this to provide contextual information between the host and views in the host's region. This approach is somewhat similar to the DataContext, but it does not rely on it.
Shared services. Callers can call a method on the service which raises an event to the receiver of the message. Use this if none of the preceding is applicable.
In your case you should use EventAggregator or RegionContext. Shared ViewModel is possible but this is the last resort.
Related
In my WPF application, I have several models and viewmodels. Consider an example:
The SurfaceCondition property of my RoadViewmodel changes. I want this to (asynchronously) trigger a change of the Wheel property of my CarViewmodel.
I can think of several solutions, but I sense this particular problem has a well-recognized solution. Using messages? Putting a reference in the RoadViewmodel to the CarViewmodel and trigger an update through the property? Merging the viewmodels? WPF gurus out there, please enlighten me!
Definitely not the two last solutions you propose as they violate Seperation Of Concerns (RoadViewModel knowing about CarViewModel) / DRY principles (RoadViewModel having to update CarViewModel or merging two classes).
Messages on the other hand seems like a fine, decoupled solution here. There are a couple of implementations available, for example Prism has en EventAggregator class, MVVM Toolkit has MessageBus etc. Or search for terms like 'MVVM event bus'. Now whatever you choose, know that it is always good to not use those classes directly but instead pass an interface. For example with Prism, you'd program your viewmodels to use the IEventAggregator interface only. In the actual application you pass them an instance of the actual EventAggregator, whereas during unit tests you pass the a mock.
I am new to WPF MVVM .. Anybody clear the usage of the Behaviors in MVVM application in WPF?. Why we should go for Behavior even we have Method action in WPF MVVM ?
A Behavior is the thing you attach to an element and specifies when the application should respond.
The Action is attached to the behavior and defines what the application should do when the behavior is triggered.
From this article:
At a glance, a behavior looks similar to an action: a self-contained
unit of functionality. The main difference is that actions expect to
be invoked, and when invoked, they will perform some operation. A
behavior does not have the concept of invocation; instead, it acts
more as an add-on to an object: optional functionality that can be
attached to an object if desired. It may do certain things in response
to stimulus from the environment, but there is no guarantee that the
user can control what this stimulus is: it is up to the behavior
author to determine what can and cannot be customized.
And from this article:
Behaviors let you encapsulate multiple related or dependent activities
plus state in a single reusable unit.
I highly recommend reading Introduction to Attached Behaviors in WPF that demonstrates:
What is attached behavior
What are it's alternatives
It's advantages compared to alternative solutions to similar problems
The idea is that you set an attached property on an element so that you can gain access to the element from the class that exposes the attached property. Once that class has access to the element, it can hook events on it and, in response to those events firing, make the element do things that it normally would not do. It is a very convenient alternative to creating and using subclasses, and is very XAML-friendly.
Conclusion from the above article:
Hooking an event on an object and doing something when it fires is
certainly not a breakthrough innovation, by any stretch of the
imagination. In that sense, attached behaviors are just another way to
do the same old thing. However, the importance of this technique is
that it has a name, which is probably the most important aspect of any
design pattern. In addition, you can create attached behaviors and
apply them to any element without having to modify any other part of
the system. It is a clean solution to the problem raised by Pascal
Binggeli, and many, many other problems. It's a very useful tool to
have in your toolbox.
In MVVM you may need to call methods from the View if your ViewModel exposes methods, not commands. Behaviors allow for this.
You state "we have Method action in WPF MVVM", but as far as I know "method action" is not part of WPF. If you are using a helper MVVM library, it may provide "method action" that could encapsulate methods in commands. In such a case, behaviors are not required for the MVVM pattern using methods.
Note, though, that behaviors have other uses outside of MVVM.
With current practices (at least with WPF and Silverlight) we see views bound via command bindings in the view model or we at least see view events handled in view models. This appears to be a violation of SRP because the view model doesn't just model the view state, but responds to the view (user). Others have asked how to build view models without violating SRP or asked whether their implementations do so (this last is the controller in MVC, but roughly analogous).
So are current practices a violation of SRP? Or is "view model" really a collection of things that don't violate SRP? To frame this a bit, it seems we need to know what is the single responsibility or if there are multiple responsibilities in the concept, are the individual responsibilities split out, conforming to SRP. I'm not sure.
Wikipedia's definition of view model says
[T]he ViewModel is a “Model of the View” meaning it is an abstraction of the View that also serves in data binding between the View and the Model
This seems good enough for SRP, but then the entry later says (my emphasis added)
[The ViewModel] acts as a data binder/converter that changes Model information into View information and passes commands from the View into the Model
In a Prism blog post about the view model's role, the author says (again, my emphasis)
What it boils down is that the view model is a composite of the following:
an abstraction of the view
commands
value converters
view state
I'm sure I've missed many definitions out there, but they seem to fall into these categories:
Single "vague" responsibility of modeling view state (so what do we
mean by state)
Multiple responsibilities (view state, user interaction (i.e.
commands))
A composite of single specific responsibilities (abstraction,
state, interaction, conversion), thus having a single
responsibility: "managing all that stuff".
If you're curious, I "care" about this because (2) feels right, but seems counter to the prevailing implementations.
Single Responsibility as Martin defines it:
"THERE SHOULD NEVER BE MORE THAN ONE REASON FOR A CLASS TO CHANGE."
A ViewModel, as far as MVVM is concerned is really just a specialized implementation of a Presentation Model.
So while it could be argued that a Presentation Model should only represent the state of the UI, and that a Presenter/Controller should always broker the commands between the UI and the Presentation Model. If one follows this idea, with SRP dividing on State and Commands, then adding a command should not affect the class that represents state. Therefore MVVM would break SRP.
However...
I think this is grasping at straws. MVVM is a fairly specialized implementation used basically in WPF/Silverlight (and now browser clients).
Patterns are designed to make designs simpler where the alternative would be more cumbersome or less maintainable. Since MVVM is designed to take advantage of the extremely rich data binding capabilities of the presentation technologies, then it is a worthwhile trade off.
No! MVVM does not violate SRP, (the programmer does, lol!)
There is no reason that using the MVVM pattern needs to ignore the SRP. MVVM does not mean that there is only one Model Class, one View-Model Class, and one View Class. Certainly, if you only had one View Class, you could only ever show one simple screen.
Those classes that are in the View tier, should be responsible for one thing; doing, deciding, or containing. A View can consist of several sub-views who's jobs are to do certain pieces of the users interractions. Consider a basic form, it has a display grid, items in the grid can be edited, and there is a "Save" button.
The main View would be a container for two other views; the datagrid (a user control, or something) and a command control. The datagrid then is responsible for choosing the right childview to render data in; in essense it's a container that databinds. The View to edit items is a child view of the datagrid, which is in-turn a child of the main View. Lastly the command control is a set of buttons (in this case a single one) who's single responsibility is to raise signals that commands have been issued by the user.
In this way the Edit View (used by the DataGrid) is agnostic about what uses it, and has one responsibility; Same with the command control. Likewise the DataGrid doesn't care about who uses it, only that it can contain the Edit View (child). Nice SRP there.
ViewModels to match the Views (and children) are also responsible for one thing. The Edit View Model is a container to which the Edit View Binds; it simply contains the data fields that can be displayed/edited. It doesn't care about anything but signalling when one of its properties change. The Command Button View Model is a class that does things. It's commands are bound to the buttons, and it will do work based on what the user clicks on. It will have to have access to other parts of the ViewModel(s) to do it's work.
The main page View Model is there to contain the other child views. It's sole responsibility is as an initializer, making all the required ViewModel instances, and passing constructor parameters to other ViewModel instances (say, the Command Button View Model so it knows where to get data for it's work)
It's natural to cram a whole bunch of functionality into a single ViewModel that a large View would bind to. But it doesn't have to be that way, and SRP can be maintained in MVVM.
The main goal of MVVM is to allow for testable design, the Model layer can be tested independantly, all classes in the Model can easily follow SRP. The ViewModel can be tested without the need of a view; it gets trickier to think SRP in the ViewModel, but it is certainly doable; just remember to break out your classes so they only have one concern. The View is bound to parter ViewModels, with any luck, your testing of the ViewModel makes snapping the View(s) on super easy. Remember you can have each View-let adhere to SRP to be part of a larger conglomerate View (container).
TL;DR?
To answer your question directly, the View is a collection of classes that does not break the SRP. Thus, when the ViewModel is abstracted from the View(s) (View-First), they are also a collection of classes that adhere to good SRP.
I consider many of the current practices around MVVM violate SPR (at least). This is yet another situation where simply adding controllers back to MVVM would solve all the problems cleanly. I call it MVCVM :)
The pattern we are using successfully on all recent projects is to register controllers only, in modules, and initialise them at startup. The controllers are very light/slim and the only thing that needs to hang around for the life of the app listening for, or sending, messages. In their initialise methods they then register anything they need to own (views and viewmodels etc). This lightweight logic-only-in-memory pattern makes for slimmer apps too (e.g. better for WP7).
The problem with just using VMs, as you have found, is that eventually you hit cases where they need to know about views, or commands, or other stuff no self-respecting ViewModel should be involved with!
The basic rules we follow are:
Controllers make decisions based on events
Controllers fetch data and place it in appropriate View Model properties
Controllers set ICommand properties of View Models to intercept events
Controllers make views appear (if not implied elsewhere)
View Models are "dumb". The hold data for binding and nothing else
Views know they display a certain shape of data, but have no idea where it comes from
The last two points are the ones you should never break or separation of concerns goes out the window.
Simply adding controllers back into the MVVM mix seems to solve all the problems we have found. MVVM is a good thing, but why did they not include controllers? (but this is of course just my opinion) :)
What it boils down is that the view model is a composite of the following:
an abstraction of the view
commands
value converters
view state
I don't see why you've separated the first two items. Commands are part of the view.
As for the rest - you're right. In some cases. I've built applications where the tasks of value conversion and maintaining view state were sufficiently complex that it didn't make sense for a single view model class to do it all, and I broke them out into separate classes that interoperate with the VMs.
So?
I'm using MVVM Light toolkit (which I love). I currently have messaging in place for some interaction originating from the ViewModel and intended for consumption by the View. Typically these types of messages indicate the View should do something like hide itself, show a confirmation message that data was saved, etc.
This works. In the constructor for the View, I register with the Messenger:
Messenger.Default.Register<NotificationMessage<PaperNotification>>(this, n => HandlePaperNotification(n));
When I'm using the Messenger to communicate cross-cutting concerns between ViewModels (like identity), I can see that when the ViewModel is cleaned up in the ViewModelLocator, the base class for ViewModels (ViewModelBase) unregisters any subscribed messages. I don't have to do anything, as MVVM Light Toolkit handles that for me. However, when I use them in the Views, I have to expressly unregister them at Closing time, like so:
Messenger.Default.Unregister(this);
I suppose I could implement a base class for Views to inherit from.
However, it strikes me that perhaps this is a code smell to be using the Messenger in the View... it works, but it might not be the best way. I'm wondering if I should instead create a property on the ViewModel and bind whatever part of the View's elements to it. In the example of hiding a form, a property could be a boolean called "Show". As I think about it, I can see that in many cases this will result in having to write a ValueConverter. One way seems less testable. The other way seems to require much more code and perhaps the introduction of excess ValueConverters, which could become a code smell in themselves.
So (after all that build up) my question is this:
Is it preferable to use messages within the View or is it better to add properties (and potentially ValueConverters) to allow the ViewModel to drive it in a more bindable fashion?
In MVVM. ViewModel comunicates with View through DataBinding and Commands. If you need some other functionality, you need to implement it using this means.
Messaging is supposed to be only for ViewModels. Views are supposed to be "stupid" visualisers of your data in ViewModel.
The Messaging logic in MVVM Light is there for communication between ViewModels. I've never run into any communication between View and ViewModel that I couldn't solve with binding and/or commands. Sometimes I need Value Converters and sometimes I need code in the code-behind, but I've never had to make the ViewModel directly push data to the View.
This is an interesting discussion and I found this thread when I was wondering about view model to view communication. Interestingly, MVVMLight's creator seems to find it perfectly acceptable to send messages from a view model to a view. Another example of differing opinions about what is a good MVVM design.
I have an MVVM application. In one of the ViewModels is the 'FindFilesCommand' which populates an ObservableCollection. I then implement a 'RemoveFilesCommand' in the same ViewModel. This command then brings up a window to get some more user input.
Where/what is the best way to do this whilst keeping with the MVVM paradigm? Somehow
doing:
new WhateverWindow( ).Show( )
in the ViewModel seems wrong.
Cheers,
Steve
I personally look at this scenario as one where the main window view model wants to surface a task for the end user to complete.
It should be responsible for creating the task, and initializing it. The view should be responsible for creating and showing the child window, and using the task as the newly instantiated window's view model.
The task can be canceled or committed. It raises a notification when it is completed.
The window uses the notification to close itself. The parent view model uses the notification to do additional work once the task has committed if there is followup work.
I believe this is as close to the natural/intuitive thing people do with their code-behind approach, but refactored to split the UI-independent concerns into a view model, without introducing additional conceptual overhead such as services etc.
I have an implementation of this for Silverlight. See http://www.nikhilk.net/ViewModel-Dialogs-Task-Pattern.aspx for more details... I'd love to hear comments/further suggestions on this.
In the Southridge realty example of Jaime Rodriguez and Karl Shifflet, they are creating the window in the viewmodel, more specifically in the execute part of a bound command:
protected void OnShowDetails ( object param )
{
// DetailsWindow window = new DetailsWindow();
ListingDetailsWindow window = new ListingDetailsWindow();
window.DataContext = new ListingDetailsViewModel ( param as Listing, this.CurrentProfile ) ;
ViewManager.Current.ShowWindow(window, true);
}
Here is the link:
http://blogs.msdn.com/jaimer/archive/2009/02/10/m-v-vm-training-day-sample-application-and-decks.aspx
I guess thats not of a big problem. After all, the Viewmodel acts as the 'glue' between the view and the business layer/data layer, so imho it's normal to be coupled to the View (UI)...
Onyx (http://www.codeplex.com/wpfonyx) will provide a fairly nice solution for this. As an example, look at the ICommonDialogProvider service, which can be used from a ViewModel like this:
ICommonFileDialogProvider provider = this.View.GetService<ICommonDialogProvider>();
IOpenFileDialog openDialog = provider.CreateOpenFileDialog();
// configure the IOpenFileDialog here... removed for brevity
openDialog.ShowDialog();
This is very similar to using the concrete OpenFileDialog, but is fully testable. The amount of decoupling you really need would be an implementation detail for you. For instance, in your case you may want a service that entirely hides the fact that you are using a dialog. Something along the lines of:
public interface IRemoveFiles
{
string[] GetFilesToRemove();
}
IRemoveFiles removeFiles = this.View.GetService<IRemoveFiles>();
string[] files = removeFiles.GetFilesToRemove();
You then have to ensure the View has an implementation for the IRemoveFiles service, for which there's several options available to you.
Onyx isn't ready for release yet, but the code is fully working and usable at the very least as a reference point. I hope to release stabilize the V1 interface very shortly, and will release as soon as we have decent documentation and samples.
I have run into this issue with MVVM as well. My first thought is to try to find a way to not use the dialog. Using WPF it is a lot easier to come up with a slicker way to do things than with a dialog.
When that is not possible, the best option seems to be to have the ViewModel call a Shared class to get the info from the user. The ViewModel should be completely unaware that a dialog is being shown.
So, as a simple example, if you needed the user to confirm a deletion, the ViewModel could call DialogHelper.ConfirmDeletion(), which would return a boolean of whether the user said yes or no. The actual showing of the dialog would be done in the Helper class.
For more advanced dialogs, returning lots of data, the helper method should return an object with all the info from the dialog in it.
I agree it is not the smoothest fit with the rest of MVVM, but I haven't found any better examples yet.
I'd have to say, Services are the way to go here.
The service interface provides a way of returning the data. Then the actual implementation of that service can show a dialog or whatever to get the information needed in the interface.
That way to test this you can mock the service interface in your tests, and the ViewModel is none the wiser. As far as the ViewModel is concerned, it asked a service for some information and it received what it needed.
What we are doing is somethng like that, what is described here:
http://www.codeproject.com/KB/WPF/DialogBehavior.aspx?msg=3439968#xx3439968xx
The ViewModel has a property that is called ConfirmDeletionViewModel. As soon as I set the Property the Behavior opens the dialog (modal or not) and uses the ConfirmDeletionViewModel. In addition I am passing a delegate that is executed when the user wants to close the dialog. This is basically a delegate that sets the ConfirmDeletionViewModel property to null.
For Dialogs of this sort. I define it as a nested class of the FindFilesCommand. If the basic dialog used among many commands I define it in a module accessible to those commands and have the command configure the dialog accordingly.
The command objects are enough to show how the dialog is interacting with the rest of the software. In my own software the Command objects reside in their own libraries so dialog are hidden from the rest of the system.
To do anything fancier is overkill in my opinion. In addition trying to keep it at the highest level often involving creating a lot of extra interfaces and registration methods. It is a lot of coding for little gain.
Like with any framework slavish devotion will lead you down some strange alleyways. You need to use judgment to see if there are other techniques to use when you get a bad code smell. Again in my opinion dialogs should be tightly bound and defined next to the command that use them. That way five years later I can come back to that section of the code and see everything that command is dealing with.
Again in the few instances that a dialog is useful to multiple commands I define it in a module common to all of them. However in my software maybe 1 out of 20 dialogs is like this. The main exception being the file open/save dialog. If a dialog is used by dozens of commands then I would go the full route of defining a interface, creating a form to implement that interface and registering that form.
If Localization for international use is important to your application you will need to make sure you account for that with this scheme as all the forms are not in one module.