MVVM: commands vs eventhandlers - silverlight

I know this has been done to death, but most answers are along the lines of "yeah, you can use eventhandlers in place of commands if you like". This still doesn't solve the problem of whether writing complicated commands is warranted vs just wiring up eventhandlers in code behind to call testable methods in your view model.
I don't like commands because they produce a lot of boilerplate code and don't give me any benefit over normal methods, plus some of them (such as drag & drop) are a pain to implement.
What's wrong with writing:
codebehind:
private void Button_Click(object sender, RoutedEventArgs e)
{
viewModel.LoadData();
}
viewmodel:
public void LoadData()
{
//....
}
This is equally testable (if not more) as any command is. IMO, as long as UI specific stuff isn't leaking into your business logic, there's really no need to waste time on complicated patterns like that. Thoughts?

What's wrong with writing
Nothing - for the most part.
There is nothing wrong with using code behind, if you are careful to keep the business logic out of the code behind file. This is delegating this directly to the ViewModel, which is reasonable.
That being said, there are a couple of potential downfalls here in terms of long term maintainability:
By doing this, you're coupling the View to the ViewModel more tightly. While this is a reasonable thing to do (the View, in reality, always knows about the ViewModel), it does prevent potential reuse of View components in some scenarios, as using an ICommand allows you to have the same View be used with potentially different ViewModels. (This is rare in practice, however.)
This starts a slippery slope - by adding "any" code into code behind, you're opening up the potential that another developer will add "just one more line" in there. Over time, this can lead to a mess.
It's adding code into another place that has to be maintained. Now you'll have to maintain the ViewModel .cs file, your .xaml file, and the code behind file.
You're hard-wiring this logic into a Button. If you decide to change controls, use a gesture, etc., you'll have to remember to rework this logic.

I was in your boat at first, I even asked basically the same question here. But I came around and came to really like commands.
Some commands really are complex enough in and of themselves to warrant testing. They are just as testable as anything else on your viewmodel.
ICommand also includes CanExecute and CanExecuteChanged, which enables your view to intelligently enable/disable itself pretty much for free. This is fantastic in complex views.
Commands make it easier to change your view around, most controls have a Command property you can bind to, and simply moving the binding around is easier than mucking with event handlers. This is especially true if you have designers working on the XAML.
You can pretty much write the entire logic of the view without the view even existing. It leads to a nice flow of build the meat all at once, then throw the interface on top all at once.
Keeping your code in one place leads to longer term maintainability.

To me a very important argument against events is forcing the UI Designer to write code to be able to test a View. And worse: every time he redesigns the View he has to rewire the events.
Commands and the behaviors in Blend make render this process obsolete and much easier.
Another problem might arise when actually using the event arguments when writing the event handler. When you want to switch to another control or another event you might have become very dependent on the event arguments making it hard to switch because the other control/event does not support the same event arguments.

Related

How to initialize a view model with properties from another view Model

My question is what is the ideal way to initialize child window in WPF, MVVM way?
I have a WPF window , let's call it as ParentWindow having its view Model class - ParentWindowViewModel. On click of a button on the ParentWindow UI , I launch a new WPF window - ChildWindow like below
ChildWindow r = new ChildWindow ();
r.ShowDialog();
r.WindowStartupLocation = WindowStartupLocation.CenterScreen;
Now, the ChildWindow has its own viewModel like - ChildWindowViewModel. The Child Window has the datacontext set in its xaml as
<Window.DataContext>
<viewModel:ChildWindowViewModel/>
</Window.DataContext>
On Click of button in the ParentWindow, When i Launch the Child Window, I need to pass certain values to the Child Window, which will be used to initialize the Child Window. Without these values the child window cannot be initialized.Every time I click the button to Launch the child window, the values being passed to child window will differ based on some other selected items in the Parent Window.
I would do something like this (without error checking):
in ParentWindow.xaml.cs
private void Some_Event_In_Parent_Window()
{
ParentWindowViewModel pvm = DataContext as ParentWindowViewModel;
ChildWindow cw = new ChildWindow(pvm.Element1, pvm.Element2);
}
int ChildWindow.xaml.cs
public ChildWindow(bool elem1, string elem2)
{
InitializeComponents();
DataContext = new ChildWindowViewModel(elem1, elem2);
}
If you are dealing with minimal elements that need to be transferred between windows/VM's, and it is mainly about sending some form of "state" or "value", then there isnt too much issue with initializing the Viewmodel in the code behind. Remember that the <viewmodel:ChildWindowViewModel/> is equivalent to DataContext = new ChildWindowViewModel() in your code behind. While yes, you can create spaghetti code, or confusing dependencies by not adhering to patterns; you can also over engineer the crap of something that did not require the effort and can be just as confusing.
I find that there is an obsession with keeping your code behind empty (i have the same obsession). Remember, that the Code behind is there for a reason, and you CAN use it. Sometimes it isnt worth over-complicating your code base by implementing some big pattern if you have a single one off requirement that can be handled in code behind with some added comments.
Aside from Event Handlers, I utilize the Code Behind for these main use cases:
There is an adjustment needed to the UI that is too complicated to handle in the XAML alone. Example: I need a weird string concatenation and logic of some inputted text fields.
There is some minimal state or data needed to be transferred between Views. (Like your requirement)
There is some sort of logic that needs to happen that is UI specific and not related to the underlying data or ViewModel. (This is rare, and almost always a small one off).
In terms of "is this ideal" for MVVM; it depends on your definition of ideal.
Can this be handled by some other design pattern? Probably...? But is it worth it.
Does implementing said pattern add bloat or overhead that only solves a small problem? Maybe. That is for you to decide.
Are you going to be repeating this implementation more than once? If so you may have some bad design to rethink.
Does implementing this solution of using Code behind solve your issue in a speedy way, that is moderately maintainable and readable? If so, then I wouldnt see a problem.
Ideal is not always defined by rules. It is also specific to your needs and requirements.
It isnt always easy to determine where your use case should be handled. View, ViewModel, maybe a Service, or a Singleton state class.
If your use case is this one window, Code behind is fine (In my opinion). If you are doing this for 20 windows, you may want a Service to maintain the state somehow. Think of it more - if your code is SOLID and DRY

What's with empty code-behinds?

I understand the benefit to unit testing of preferring the view-model over the code-behind. However, I cannot understand the obsession with achieving completely empty code-behinds. At compile time, the code behind and the XAML are combined, so they are actually the same thing. I, to, love using XAML due to its declarative nature which is very cool. But is there actually any practical reason for insisting that all view-related code be XAML rather than C#?
There are also some benefits in taking advantage of what Blend can do at design-time with XAML but that's really more of a XAML vs (the same code) in code-behind argument. For the no code-behind argument as it relates to MVVM the real goal, as you've pointed out, is to get code moved into classes like ViewModels that can be tested and reused. As with many things, this often gets taken to the extreme and people end up insisting that there never be any code-behind when what is really needed is to have no business logic in code-behind, disregarding that there is also often UI logic too.
XAML is very rich and allows you to do a lot declaratively but there are still UI specific things (i.e. event handlers, some animation handling) that can't be done without using some code. You can usually manage to move this code to some place other than the code-behind by using things like custom controls, attached properties, etc. but if you're not getting any reuse benefits out of doing that it's probably just better to use the code-behind to do that UI logic instead.
Patterns like MVVM are general guiding principles, not a set of strict rules to be obsessively adhered to - those are called programming languages. :)
On good reason is that with WPF and XAML, Microsoft aim to keep separated the graphical and coding jobs. In this way, developer and UI designer can work easilly.
It's all about testability. It's hard (nigh impossible) to unit test your code behinds. With MVVM, you can create test harnesses that fully test your Model and ViewModel.
That being said, I'm a fan of being pragmatic. Some UI events are a bear to set up using Commands, and for those, I'll sometimes drop down into the codebehind.
The view model is the code-behind for the XAML. At least, that's how I think of it. And it's a code-behind file that can be tested without the XAML.
On the other hand, as Ben Johnson might have put it, no man but a fool ever implemented drag and drop in the view model.

What is the real advantage of keeping code out of the XAML code behind?

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.

Avoid MVVM/data binding for small windows?

I've found view models to be very useful for splitting user interface and business logic code. However, I've also made the experience that for small, simple windows a view model class just adds a lot of additional code, effectively reducing maintainability instead of improving it.
Let me give you a simple, real-world example that I've had recently: A dialog window providing two (fixed-text) buttons and a customizable text block.
Using plain old x:Name-based code-behind programming technique, this is a matter of a few lines of code (set the text, handle the two button clicks by returning a value and closing the window) -- clean and simple.
Doing it the "recommended way", i.e., creating a view model class (implementing INotifyPropertyChanged or inheriting DependencyObject) and defining Commands requires an awful lot of code compared to the solution above (especially since there is no concise way to define "local variable + property + raise PropertyChanged" in VB) -- making the solution less readable and more error-prone.
So, currently I'm using the pragmatic approach of choosing between "plain old x:Name" and view model on a case-by-case basis. However, the wealth of blog/forum postings claiming that the view model should be used all the time makes me wonder whether I've overlooked something.
Did I overlook something?
I'm all for MVVM, but the window you're describing can be implemented once and then filled as needed when you want to open one. So the ViewModel might look like this:
public SmallDialogTask
{
string Title { get; set; }
string Text { get; set; }
string AcceptButtonLabel { get; set; }
string RejectButtonLabel { get; set; }
Command AcceptCommand { get; }
Command RejectCommand { get; }
}
Implement this once and use inheritance to configure the various instances where you need it. As you can see from my example, this allows you to encode much more semantics into your class.
See also DRY, my question about MVVM dialogs and -- just for reference -- my blog post about MVVM.
You can use data binding without defining a view model - and in most "small" windows there isn't mush logic - so you don't actually need change notification.
Just set DataContext = this and data-bind to properties of the window class.
Commands, on the other hand, don't have good simple version so I'll just use good old event handling.
(I also think that MVVM is overkill for a lot of not-so-small windows, but I'm obviously in the minority on that one)
I do the same.
Small dialogs and quick choice or information messages just get done in the simplest possible way. I try not to overcomplicate things with patterns that are unnecessary. The main application windows and anything larger is generally done with MVVM.
(So either you haven't missed anything, or I've missed the same thing.)
I do something similar however in the situations where i just want a very small window that does something very basic i at least implement an interface and call it through a gateway so that i can call it in a testable way. Something like this :
//eg . in a viewmodel.cs or command.cs
var sometextIwantUserToEnter = UIServices.GetMeSomethingThatCan().GetText();
My window will implement IGetText and i do all the Window showing and result checking in the window itself in the GetText method. This keeps everything isolated in the window and i can assert that the service was called in my tests.
Hope that made sense.
You don't have to implement INotifyPropertyChanged in a view model class. You only need to do this if you need change notification, which, for simple dialogs, you don't.
I can't speak to VB-specific issues, but in C# the code that results is at least as simple and concise as it would be if it lived in the window's code-behind - and frequently more so, if you try to implement commanding behavior without implementing commands. ("I'll just set IsEnabled to true in this property setter, so that the OK button is enabled once data is entered," is one of those sentences where the word "just" turns out to be a damn lie.)
The counterargument to this - "sure, but if I don't implement change notification, then I can't do X and Y when something changes a property value" - undercuts the assertion that what you're building is simple.
I find that in general, nothing is as simple as I think it's going to be when I first start it. It's a lot easier to add change notification and commands to a view model class than it is to refactor a view model class out of a window's code-behind so that I can add change notification and commands to it.
Finally, if you use simple view model classes to back simple views in all cases but one, that one case is going bite you (or some other developer) in the ass someday. There's a lot to be said for consistency if the cost of consistency is low.

What's the "right" way to isolate control dependencies

I've made it a personal rule to inherit every UI control before using it. In a previous life I'd always considered this one of the less useful things you could do because the justification always seemed to be "I might want to change the font on all the buttons at once"... a motivation that never paid off... once... ever.
Two recent projects have changed my mind about the practice, though. In the first, we needed a consistent "ValueChanged" event so that we could easily implement a "dirty" flag on our forms without a massive switch statement to choose between a Textbox's "TextChanged" event, or a ListBox's "SelectedIndexChanged" etc. We just wanted one consistent thing to listen for on all controls, and subclassing the built-in controls bought us that pretty easily.
In the second project, every effort was made to get by with the base controls because the UI was expected to be pretty simple, but a few months in, it became obvious that they just weren't going to cut it anymore, and we purchased the Telerik control suite. If we had inherited all the controls to begin with, then changing our derived controls to inherit from the Telerik controls would have applied the changes for us globally. Instead, we had to do some searching and replacing in all the form designers.
So here's my question: What are the relative strengths and weaknesses of
Simply adding a Class, and making it inherit from a control.
Adding a new "Custom Control" and inheriting.
Adding a new "Component" and inheriting.
All three have the same effect in the end, you get a new type of Button to put on your forms. I've seen all three used by different people, and everyone seems to think that their way is the best. I thought I should put this discussion on StackOverflow, and maybe we can nail down a concensus as a community as to which one is the "right" way.
Note: I already have my personal opinion of which is "right", but I want to see what the world thinks.
If both 1 & 2 are inheriting, then they are functionally identical, no? Should one of them be encapsulating a control? In which case you have a lot of pass-thru members to add. I wouldn't recommend it.
Peronally, I simply wouldn't add extra inheritance without a very good reason... for example, the "changed event" could perhaps have been handled with some overloads etc. With C# 3.0 this gets even cleaner thanks to extension methods - i.e. you can have things like:
public static AddChangeHandler(
this TextBox textbox, EventHandler handler) {
testbox.TextChanged += handler;
}
public static AddChangeHandler(
this SomethingElse control, EventHandler handler) {
control.Whatever += handler;
}
and just use myControl.AddChangeHandler(handler); (relying on the static type of myControl to resolve the appropriate extension method).
Of course, you could take a step back and listen to events on your own model, not the UI - let the UI update the model in a basic way, and have logic in your own object model (that has nothing to do with controls).
I use composition. I simply create a new UserControl and add the controls I need. This works fine, because:
I never use that many properties anyway, so pass-through methods are kept to a minimum.
I can start with a naive approach and refine it later.
Properties for look and feel should be set consistently across the site. Now I can set them once and for all.

Resources