Standalone Command Objects in WPF - wpf

Is it possible / practical to implement WPF commands as standalone objects? If so, how is this typically done? Most of the examples I see about commanding typically involve using RoutedCommand, RoutedUICommand, or some other implementation of ICommand like RelayCommand. The way these commands work in the MVVM pattern is to expose an instance of one of these types of commands through a property. Inside the ViewModel, the logic for the command is implemented as a method on the ViewModel and then passed as a delegate to the command object.
The "classic" Command pattern as I understand it would be to have each command implemented as it's own standalone object, such as an OpenCustomerViewCommand. Since the logic would be completely encapsulated in its own object, it could potentially be reused in other parts of my app. For example, if I could open the CustomerView from several places in my app it might be helpful to be able to simply create an instance of the OpenCustomerViewCommand on each ViewModel where the CustomerView could be accessed, rather than copy and paste that method into each ViewModel, and pass the delegate to a RelayCommand. If I understand correctly, the predefined ApplicationCommands such as Cut and Paste behave this way.
To me, having to provide the logic inside the ViewModel seems to diminish the value of the command pattern a bit. I suppose I don't really understand the major difference between doing it this way, and having a code behind that implements command handlers for UI events. Is there any reason I should be using the RoutedCommand pattern over the more classic approach I described above?

You could do this, but it requires some method of routing the request appropriately.
In your example, provided the OpenCustomerViewCommand knows how and where to open the "Customer View", you could easily reuse this anywhere. Instead of using a class like RelayCommand, you can just implement ICommand directly and add your logic to do this.
The problem, however, is that most commands tend to be more of an adapter for xaml to execute ViewModel-specific functionality. In most applications on which I've worked, there tend to be few commands that really need the reuse - most commands are tied to functionality specific to the ViewModel in question. As such, something like RelayCommand makes hooking this up fairly easy.

Related

Is there a better way than handling CommandBindings in code behind?

I have an application using MVVM. I'm trying to Intercept key presses on an MCE Remote control for Play, Pause, Stop etc....
Currently I'm using command bindings with a method in the code behind performing the related action on a media element as such
<Window.CommandBindings>
<CommandBinding Command="MediaCommands.Play" Executed="PlayMediaElement"/>
<CommandBinding Command="MediaCommands.Stop" Executed="StopMediaElement"/>
</Window.CommandBindings>
Before trying to include the remote control functionality I had approx 10 view-models/views with nothing in code behind.
I'm wondering if there is a better way to do this so I retain the MVVM pattern or is it perfectly acceptable/preferable to implement in this way.
EDIT - I've moved the Command Bindings from a UserControl inside a View into my MainWindow.xaml and placed the methods into MainWindow.xaml.cs. MainWindow doesn't have a view/viewmodel relationship, simply a content control with a ViewModel linked to it.
In my code behind methods I'm making use of a Mediator to send messages (Play,Pause,Stop etc...) to my mediaplayerviewmodel which in turn interacts with it's respective view. Is this a good idea or is there a better way?
I think Josh Smith created a huge confusion in his 2009 article, when he made a point that his code-behind CS files remained mostly empty. MVVM is not about not having code-behind. It is about separation of concerns. If there is any practical rule you should follow, is to make the ViewModel view agnostic (i.e. no reference from the ViewModel to the View. Think having a second unit test implementation of a 'View' for your ViewModel).
This "no code behind" confusion caused very odd structures just to work arround a problem that shouldn't have existed to begin with.
Having code behind in the MainWindow.xaml.cs is perfectly reasonable solution, as long as you don't have logic there, but simply forward the call to an appropriate method in the View Model. If that was my code I would have created custom commands (a la DelegateCommand from the same article) that binds directly to commands in the ViewModel, but your design is 100% legit as well.
Head over to Codeplex.com and look for Caliburn (or better Caliburn Micro). It extends WPF to actually allow calling of methods with arbitrary parameters pulled from other objects and the method being in the view model / controller without having a "hook method" in code behind just fowwarding the call.
The extensions can do wonderfull thignsl ike pull the value of a textbox and pass it as parameter to a method, then react on the return value - much like a view should.
You run in a limitation of "stock" wpf - which simply can only point towards method handlers in code behind without any regards to parameters. Alterantives exist, even from microsoft.

Good practice to store RelayCommand in MVVM

I need to setup different commands for ViewModels like Close, Edit, Cancel, ShowPic, ShowVideo.
Based on different ViewModels I have, I have common commands like Close, Edit, Cancel that does same operation, only context can be different. Then for other like ShowPic, ShowVideo they are belonging to their own viewmodels.
In such scenarios how to organise your commands as good practice:
Do you place them all in a separate class call "Commands"?
Do you place them inside there respective ViewModels even some are common?
Do you separate common commands from others?
Thanks for your advise and sample how you would organise them.
the answer is "2".
Even if other ViewModels have the same commands, its your injected services (read up on "IoC" if you don't know what i'm talking about) that do the heavy lifting in your ViewModels and allow you to avoid redundant logic.
Certain commands which are not view specific (e.g. Print, Save etc. which has common functionality independent of a view) can be declared as static in some static Uility class with Execute and CanExecute handlers and can be bound using x:Static attribute in XAML.
But the commands which are view specific should reside in the ViewModel.

ViewModel-first approach to Silverlight navigation

I am looking for a truly decoupled way of supporting navigation in a Silverlight application using MVVM. I am trying to accomplish more of a "purist" implementation of the pattern where the UI is completely separated from the ViewModels so that the application can actually run entirely without a UI. To do this, I need to support navigation without UI concerns.
I have several ideas how to accomplish this (with Messaging, etc) but haven't come up with a good way of "mapping" the View to the ViewModel so that the UI can show the appropriate View when the ViewModel is "displayed". I recall coming across an article some time ago that described a solution to this very problem but can't seem to locate it online anymore.
Does anyone know how to find this article or have any experience solving this problem?
So here's my somewhat long-winded description what we ended up doing:
First, we decided to use the built-in Page Navigation framework. We had multiple reasons but since it is built-in and is also the navigation framework du jour in Windows 8, we opted to try this approach.
I should also mention that we use MVVM Light and MEF in our applications. (This comes into play below.)
To make this work, we created an application Shell (UserControl) that contains the Frame control. The Shell's DataContext is set to an instance of the ShellViewModel which exposes a single CurrentPage property (of type String). We then bind the Frame's Source property to CurrentPage. This approach is similar to Rachel's app-level ViewModel.
The ShellViewModel registers with the Messenger to receive CurrentPageChanged messages. When the message is received, the CurrentPage property is updated, the PropertyChanged event raised and the UI updated. The message originates from the NavigationService (which implements INavigationService and is injected/imported using MEF).
The NavigationService exposes a NavigateTo method which accepts the string name of the ViewModel representing the destination. This name matches the contract name applied to the ViewModel when exported (using MEF) and used to lookup the instance using our ViewModelLocator.
In the NavigateTo method, we use the ViewModelLocator to retrieve the ViewModel instance, call Deactivate on the current ViewModel (if one), call Activate on the new ViewModel then send the CurrentPageChanged message with the name of the new view as a parameter. Activate/Deactivate are helper methods on the ViewModels that allow us to perform any necessary tasks when the ViewModel is navigated to or from.
This appears to be working well and gives us a very MVVM-ish implementation with all navigation isolated from our ViewModels via the INavigationService and messaging.
The only down-side right now is that while we are using string constants in code to represent the ViewModel names, we are still hard-coding the strings in the Views to set the DataContext. I will be looking into a way to set the DataContext automatically as part of the navigation 'tooling'.
I should mention that this approach was parsed together from a number of sources, including (but not limited to) Rachel and the following links:
http://blogs.microsoft.co.il/blogs/eladkatz/archive/2011/01/25/adapting-silverlight-navigation-to-mvvm.aspx
http://blog.galasoft.ch/archive/2011/01/06/navigation-in-a-wp7-application-with-mvvm-light.aspx
http://www.geoffhudik.com/tech/2010/10/10/another-wp7-navigation-approach-with-mvvm.html
Usually I have a ViewModel for the entire app, and it contains the CurrentPage and all navigation event handling.
On the View side, I use a ContentControl with it's Content bound to CurrentPage, and use a DataTemplateSelector to determine which View to display for which ViewModel
There's an example here if you're interested, although it uses DataTemplates instead of a DataTemplateSelector.

Why favor RelayCommand over RoutedCommand?

I'm trying to learn the MVVM software design pattern. I've got Matthew MacDonald's book, "Pro WPF in C# 2010" to learn WPF better. In trying to start learning MVVM I've looked at the WindowsClient.net website, especially Todd Miranda's video, "How Do I: Build Data-driven WPF Application using the MVVM pattern". In that he discusses briefly the RoutedCommand, but writes his own implementation of a class called RelayCommand based upon the ICommand interface.
This looked promising, but I've got a problem in that the window I'm developing (a simple window with textboxes, and button to issue a search using the parameters entered by the user and returning results in a listbox) is more complicated than what Todd did. Basically, I can't find a way to get the search parameters entered by the user in the RelayCommand class I've written which returns an ObservableCollection I call AllClients (that gets displayed in the listbox).
MacDonald's book discusses the RoutedCommand and especially the RoutedUICommand, and frankly this looks various promising to what I'm trying to do. However, again in an effort to better understand the MVVM pattern I've taken a quick look at what books might be available to help learn the MVVM pattern on Amazon and found some books like, "Pro WPF and Silverlight MVVM" by Gary Hall. In that book Hall seems to strongly suggest that the RoutedCommand route is not the way to go. That it is problematic and therefore it is better to use the RelayCommand.
Well, frankly, I'm really confused. First, I don't understand Hall's argument at all. Why is using RoutedCommands (or presumably RoutedUICommands as well) such a bad alternative? Why is using RelayCommands so superior?
Generally speaking, I have found that RoutedCommand is often oversized. There is a good explanation of its power in WPF ICommand vs RoutedCommand.
The superiority of RelayCommand, I think, comes from its ease of use and straightforwardness. It is instantiated with just an Executeand optionally a CanExecute event handler in the view model. This has always been just fine in situations where I just wanted to hook up some functionality to a button, menu item and the like.
If you have any parameters you need to pass the command, I would suggest having them in your view model, next to where the command implementation is located. For a search command, for instance, you would have a text box bound to a string property in your view model that contained the search text. When your command's Execute event handler is invoked, it would take that property's value and pass it to the search routine you have implemented in your model. I thus don't see a need to use the Parameters property of a command. The view model approach is just more flexible and allows for multiple parameters.

Best place to bring up new window in Model View ViewModel

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.

Resources