We have some WPF/Silverlight controls we have written using the traditional event architecture (no commands etc.), and want to convert it to MVVM compliant ones. I researched on this subject, and i take it i will have to write commands to wrap the events that i currently have in the control. I would like to design it correctly now so i want to also make it RX complaint, rather than just commands.
Can someone explain to me how i can design my currently designed events into commands and RX ones please.
It will be useful if we took something like a control's Click event, and design command for it, and also RX compliant (observable, etc.), so i can understand what is involved.
Currently it is simple events, its pretty simple to understand to work with it :)... so one can subscribe to it and execute custom handlers.
My employer wants me to make this commands and also RX-ify it.
I read some articles on these, but found it to require some PhD degree to understand (mathematical Dual, Subject<T>, etc.) :) I could not get my heads around it.
I am struggling to taking this and making it into commands and also into RX. Please help. I want to learn this properly, so i don't have to re-design it again once more.
Thanks in advance.
Paul D,
I think you may be just forcing technology for technology sake.
First you want to use the Command pattern in WPF/SL so that you can write testable code (MVVM). This is independent of Rx. If you have your ViewModel constructed correctly then if you choose to use Rx somewhere else (Repository, Model, Controllers etc) then great.
The reason that WPF uses commands instead of the Event pattern is because a command tells something to happen, where as an event broadcasts that something did happen. When you write a Control it is fine for you to broadcast that a Click occured, but in you ViewModel a command reflects that something should happen.
If we look at an example:
a SubmitOrderCommand may initiate a call to submit the state of the Model to a repository. This in itself does not need to involve Rx. The progress of the Submission however, may utilise Rx to publish the state changes eg Submitting-->Submitted-->CreditChecked-->Accepted.
This may then result in a some contracts that look like this (psuedo code)
class OrderEntryViewModel
{
public ICommand SubmitOrderCommand { get; }
}
interface IOrderRepository
{
IObservable<OrderStatus> SubmitOrder(SubmitOrderRequest request);
}
I agree with you that there is way too much Academia around Rx. I recomment that you check out my blog introduction to Rx. I hope it helps you grasp Rx much faster.
UPDATE: Check out my book IntroToRx.com instead. It replaces the blog series.
I have no idea about ReactiveXaml but if you want to bind events to command, I could advise you MVVM light. You can try something similar to the code below, moreover MVVM light is provided with an EventToCommand Sample:
<Window
...
xmlns:Interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras"
/>
<ComboBox ItemSource="{Binding MyCollection}">
<Interactivity:Interaction.Triggers>
<Interactivity:EventTrigger EventName="SelectionChanged">
<cmd:EventToCommand Command="{Binding Path=LoadCommand}" />
</Interactivity:EventTrigger>
</Interactivity:Interaction.Triggers>
</ComboBox>
Related
I'm learning the MVVM pattern with a new(small) project, and I've one question about the way to invoke actions on our controller:
I saw many tutorial where they were telling us to use Command, implying to declare a RelayCommand, initialize it and create the action called by the RelayCommand.
In the other side, I've a colleague which said me that I can use the CallMethodAction with a trigger:
<i:Interaction.Triggers>
<i:EventTrigger>
<ei:CallMethodAction MethodName="Init" TargetObject="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
For me, his approach has the advantage that I don't have to make some inits methods for commands(which may be never used).
So what am I missing? Why everybody use commands?
Commands are out-of-the-box solution and can be attached only to elements which implement the ICommand interface. On the other hand, event triggers can be attached to any event, what makes them more flexible. I follow the general strategy to use Commands where user interactions are involved (buttons, menus) and CanExecute pattern is needed. My commands are strictly connected to visual interface (provide caption, image source, etc.). I use CallMethodAction in any other situation when I want to get rid of code-behind.
Commands provide functionality for disabling in ViewModel code. That can be used to automatically disable e.g buttons bound to command. That's what makes Commands better. Besides, based on your logic you could just dynamically pluck another Command in the same slot and it will reroute the traffic from View, whereas in CallMethodAction you would have to write the rerouting logic in the called method, which would be ugly.
As you can see, it depends on what you try to accomplish and how complicated is your logic :)
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.
There is a lot of effort in the Silverlight community to keep a XAML's code behind file as free of code as possible. What is the real motivation behind this?
For example, what is the advantage of using a command instead of an event handler? If I have
<Button x:Name="SaveButton" Content="Save" Click="SaveButton_Click" />
...
private void SaveButton_Click(object sender, RoutedEventArgs e) {
_myViewModel.SaveChanges();
}
Then why is this prefered?
<Button x:Name="SaveButton" Content="Save" Command="{Binding SaveCommand}" />
Where obviously the SaveCommand in my view model is effectively going to invoke SaveChanges().
This can lead to situations where the view is 100% XAML, even instantiating the view model in XAML, and the connections between the view and view model are completely done through binding. Sure it's clean, but what else is it? Flexible? Why? the view still needs to work with the proper ViewModel, so if the connection between the two exists and is implicit, why not make it more explicit? It also has the disadvantage of losing compile time support. If I hook my button up to an event handler that doesn't exist, the compiler will tell me. It won't if I bind to a non-existent command.
There is a lot of effort in the
Silverlight community to keep a XAML's
code behind file as free of code as
possible. What is the real motivation
behind this?
I would say that people who want the code behind "as free of code as possible" are those who have jumped on the MVVM bandwagon without really getting the point. (Either that or you have misinterpreted their point).
The point is not to keep the code-behind free of code, but to make sure that the View is only responsible for visual presentation. That fact that many visual aspects can be defined declaratively means there is less code in the code-behind, but it does not mean you should hesitate to write code-behind where you feel it is necessary and does not transgress outside the view's responsibilities.
what is the advantage of using a
command instead of an event handler?
A Command offers at least two capabilities that an event handler doesn't. Some WPF controls are aware of the CanExecute property of the Command, so for example a button can be disabled when the command is not available to execute. Also the designer and binding framework are Command aware.
If you just want to call a method on a button press there is no great advantage to using Commands instead of just calling the method from an event handler. So don't be afraid to use this approach. (A third approach, which favours designer over programmer, is to use the CallMethodAction from Blend 4).
It makes unit testing and / or TDD easier. By using MVVM and commanding, I can essentially build my view model and commands TDD style and have most of the view logic tested without actually having the XAML view at all.
There are probably many arguments you might hear for it but pragmatically there is only one, testability. A ViewModel delivers little unless you build a unit test for it, which in turn implies that you would need to create the ViewModel in such a way that you can unit test it, using techniques such as dependency injection, IoC, blah, blah, etc, etc.
The result is that unit tests can cover a larger part of your applications code than you could achieve had you kept the UI code more integrated.
I'm not necessarily recommending it, to do it properly takes considerable design effort and forethought. Hence the costs in building such an approach are quite high, however, the savings of the increased quality may well offset those costs.
The main advantage I see with the command is when you have the dual requirement of executing an action and validating that the action can execute (i.e. context). In other words, if you are simply linking the click with a straight method call, I agree, I see no advantage either. If the click should be conditioned, however, and the button disabled based on context, then the binding facilitates this through the CanExecute property.
This way, instead of having to worry about controls in the view (i.e. having the logic that says "find this control, and set it to disabled because we can't execute it right now) we can create a command and simply ensure that can execute returns false. This is testable independent of the view and once you do bind it, the binding itself takes care of managing the control's enabled property.
I am new to WPF and MVVM, and I am working on an application utilizing both. The application is similar to windows explorer, so consider an app with a main window with menu (ShellViewModel), a tree control (TreeViewModel), and a list control (ListViewModel). I want to implement menu items such as Edit -> Delete, which deletes the currently selected item (which may be in the tree or in the list).
I am using Josh Smith's RelayCommand, and binding the menuitem to a DeleteItemCommand in the ShellViewModel is easy. It seems like implementing the DeleteItemCommand, however, requires some fairly tight coupling between the ShellViewModel and the two child view models (TreeViewModel and ListViewModel) to keep track of the focus/selection and direct the action to the proper child for implementation. That seems wrong to me, and makes me think I'm missing something.
Writing a focus manager and/or selection manager to do the bookkeeping does not seem too hard, and could be done without coupling the classes together. The windowing system is already keeping track of which view has the focus, and it seems like I'd be duplicating code.
What I'm not sure about is how I would route the command from the ShellViewModel down to either the ListViewModel or the TreeViewModel to do the actual work without making a mess of the code. Some day, the application will be extended to include more than two children, and I want the shell to be as ignorant of the children as possible to make that extension as painless as possible.
Looking at some sample WPF/MVVM applications (Karl Shifflett's CipherText, Josh Smith's MVVM Demo, etc.), I haven't seen any code that does this (or I didn't understand it).
Regardless of whether you think my approach is way off base or I'm just missing a small nuance, please share your thoughts and help me get back on track. Thanks!
There are some inherent issues with Josh Smith's implementation of MVVM. Take a look at Ward Bell's post on the subject: http://neverindoubtnet.blogspot.com/2010/03/mvvm-josh-smiths-way.html. You may want to take a look at some alternative MVVM frameworks such as Caliburn that take a ViewModel first approach and break this coupling.
The RelayCommand is just a way to get a command in your ViewModel that can be bound to your View.
I think I would be inclined to step back from all of the different MVVM architectural variations and sample apps, and just use good old OOD. Why not have a ViewModel base class of some sort (ie, DetailsViewModelBase) for TreeViewVm and ListViewVm. Put a DeleteCommand in there with CanDelete and Delete methods that have as much implementation as the subclasses share (or abstract if none), and a SelectedItem as well. Then bind the SelectedItem to the controls similar to the xaml below:
<ListView AlternationCount="2" MinHeight="250" MaxHeight="400"
ItemsSource="{Binding Projects.View}"
IsSynchronizedWithCurrentItem="True"
SelectedItem="{Binding SelectedProject, Mode=TwoWay}"
behaviors:SelectionBehavior.DoubleClickCommand="{Binding PickCommand}"
ItemContainerStyle="{StaticResource listingRowStyle}"
>
The key bindings being SelectedItem and IsSynchronizedWithCurrentItem.
HTH,
Berryl
I found a blog post by Kent Boogaart that describes what he calls an ActiveAwareCommand. This seems to do what I was looking for, although I haven't yet tried it. A comment on the post mentions Prism's IActiveAware as having similar behavior.
Is anyone using the SLExtensions command pattern (http://www.codeplex.com/SLExtensions) for associating commands to Silverlight control events? From what I've seen, you can only attach a command for one event per control. For example, you can only add a click event for a button, a keydown event for a textbox, etc.
What if I wanted to add multiple events per control? For example, what if I wanted to add commands for both Click and Drop events for a button. Out of the box there does not seem to be a way to handle this with the SLExtensions code.
BTW, this is in a Model-View-ViewModel (MVVM) context.
Which events you wire upto in the XAML are a little limited, but but there's nothing to stop you doing it in the code behind/view model if it's not naturally supported by SLExtensions.
if (action == dropped)
{
Commands.Dropped.Execute();
else
{
Commands.Clicked.Execute();
}
Or whatever... if I've misunderstood you, some sample code of what you want to do would be helpful.
dwynne - You're absolutely correct. I could handle the drop event using the code you specified. However, I would still have to implement the event handler in my code-behind then call my ViewModel from there. I'm trying to adhere to MVVM by attempting the eliminate coding event handlers into my code-behind. Instead, I would like to wire-up my XAML to my ViewModel directly by using the attached commands.
The SLExtensions library allows you to do this but (from what I've experienced) only allows one event per control (Click for button, keydown for textbox, etc). For any non-trivial application this is not sufficient and your MVVM implementation breaks down.
Sorry for not using the comments area but 300 characters is a bit limiting. StackOverflow people - you need to up this limit.
I'm not familiar with SLExtensions but in WPF you have the same limit of one command per control, which is associated by the control implementation. If you want a command to execute for another event, you have to wire that yourself. However, there is a solution that doesn't require you to do this wiring in the code behind... attached behaviors. In fact, Caliburn (http://www.codeplex.com/caliburn) does just this with its "Action" concepts. I've not looked at Caliburn in a long time, and have no idea if it's Silverlight compatible, but you can certainly look into how the Actions are codified there and implement your own.