General question on MVVM
-
I was reading through posts such as this one on MSDN[^], and I was wondering why in MVVM, we constantly try to save 10 lines of code in the .xaml.cs class by adding 100 lines in the viewmodel or helper classes. Can someone tell me the main benefit of taking such big hits in code size and readability to avoid putting code in the .xaml.cs file? I would think that even if you do regular event handling in the .xaml.cs file, it still follows the textbook MVVM pattern (view knows viewmodel, viewmodel knows model, no other knowledge allowed).
-
I was reading through posts such as this one on MSDN[^], and I was wondering why in MVVM, we constantly try to save 10 lines of code in the .xaml.cs class by adding 100 lines in the viewmodel or helper classes. Can someone tell me the main benefit of taking such big hits in code size and readability to avoid putting code in the .xaml.cs file? I would think that even if you do regular event handling in the .xaml.cs file, it still follows the textbook MVVM pattern (view knows viewmodel, viewmodel knows model, no other knowledge allowed).
The idea is simple. Seperation of Concerns, aka SOC. The View should only do 'View' things and the 'View Model' should interpret the Model for the View to handle. If the view starts doing some of the interpretation or business logic you are now coupled to your view. This becomes problamatic in many cases 1.) UI stack changes - ummm Metro anybody? 2.) End users want same logic but to simply look different - "Can you make it pink" "No he can't cause we want it blue" 3.) Although the view knows about the view model until you actual do some event binding it really just knows about the API. In fact it is not even coupled to that though. Meaing if you bind to a property called "Name" and there is no name it will still run, you just won't see the name. However if you do something like (this.DataContext as SomeViewModel).SomeEvent += ViewEventHandler, then you have truely coupled that view model to the view. I have seen this many places and 'usually' it is OK, but I have also seen things in the event handler that turn it into fully coupled view to view model systems (e.g. View processes on source collection to re-render, initialize data etc.). In essence although you can do things quickly that way it can lead to a broken system down the road. Just like I can name my variables 'x', 'y' and 'z' saving me key strokes. But in the end that is just bad practice. To conclude I will say putting stuff in the xaml.cs file is fine when it is view based. Sometimes it makes sence. Following a strict guideline of not putting anything there is silly.
Computers have been intelligent for a long time now. It just so happens that the program writers are about as effective as a room full of monkeys trying to crank out a copy of Hamlet.
-
The idea is simple. Seperation of Concerns, aka SOC. The View should only do 'View' things and the 'View Model' should interpret the Model for the View to handle. If the view starts doing some of the interpretation or business logic you are now coupled to your view. This becomes problamatic in many cases 1.) UI stack changes - ummm Metro anybody? 2.) End users want same logic but to simply look different - "Can you make it pink" "No he can't cause we want it blue" 3.) Although the view knows about the view model until you actual do some event binding it really just knows about the API. In fact it is not even coupled to that though. Meaing if you bind to a property called "Name" and there is no name it will still run, you just won't see the name. However if you do something like (this.DataContext as SomeViewModel).SomeEvent += ViewEventHandler, then you have truely coupled that view model to the view. I have seen this many places and 'usually' it is OK, but I have also seen things in the event handler that turn it into fully coupled view to view model systems (e.g. View processes on source collection to re-render, initialize data etc.). In essence although you can do things quickly that way it can lead to a broken system down the road. Just like I can name my variables 'x', 'y' and 'z' saving me key strokes. But in the end that is just bad practice. To conclude I will say putting stuff in the xaml.cs file is fine when it is view based. Sometimes it makes sence. Following a strict guideline of not putting anything there is silly.
Computers have been intelligent for a long time now. It just so happens that the program writers are about as effective as a room full of monkeys trying to crank out a copy of Hamlet.
I can see how keeping the business logic in the viewmodel makes sense, in which case doing normal event handling in the .xaml.cs file that calls a public method in the viewmodel would seem to suffice. In the accepted answer in the MSDN thread I linked to, the answerer creates a static class (that the viewmodel is aware of) that specifically knows that the data is bound to a DataGrid (and not a Listview or a third-party data control). That sounds like a severe violation of the MVVM principle to me, in addition to being a pain in the butt to code and maintain. However, I can't seem to find any examples of handling events that aren't the standard Command event (such as double-click, enter, or leave) elegantly without doing regular event handling in the xaml.cs file, which is frowned upon for some reason. It feels like there is no real standard, and people are just juggling back and forth between competing bad practices and never really landing anywhere. I'm coding a bunch of WPF interfaces now, and I'd like me and my whole team to have a solid idea of what the best practice is.
-
I can see how keeping the business logic in the viewmodel makes sense, in which case doing normal event handling in the .xaml.cs file that calls a public method in the viewmodel would seem to suffice. In the accepted answer in the MSDN thread I linked to, the answerer creates a static class (that the viewmodel is aware of) that specifically knows that the data is bound to a DataGrid (and not a Listview or a third-party data control). That sounds like a severe violation of the MVVM principle to me, in addition to being a pain in the butt to code and maintain. However, I can't seem to find any examples of handling events that aren't the standard Command event (such as double-click, enter, or leave) elegantly without doing regular event handling in the xaml.cs file, which is frowned upon for some reason. It feels like there is no real standard, and people are just juggling back and forth between competing bad practices and never really landing anywhere. I'm coding a bunch of WPF interfaces now, and I'd like me and my whole team to have a solid idea of what the best practice is.
You may be misunderstanding the solution. It is what we refer to as an "AttachedBehavior". That is one method. I prefer to use System.Interactivity to capture standard events.
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
You can then use command wrappers (e.g. GalaSoft has an EventToCommand Wrapper or make your own) to fire a command in the ViewModel. Using Attached behaviors is also another way as was shown. I do understand your dillemna though and the reason being is you want to react business logic to UI logic but it is not set up in the framework for you. In comparison a button has a "Command" that you can bind to so it is there for you. You can however set up the logic has was shown. This does require adding DPs and appropriately attaching etc. It may seem like a lot of work but the thing is you can re-use the attached behavior anywhere. Therefore the advantage is you still kept your view and vm decoupled even if you had to use the UI effect in numerous places. [Edit] Yet another way to strap an event command using the same library.
I did this in a silverlight app because the DataGrid does not have a bindable SelectedItem. This was the easiest way IMO to pass the Selected item to the VM then.
Computers have been intelligent for a long time now. It just so happens that the program writers are about as effective as a room full of monkeys trying to crank out a copy of Hamlet.
-
You may be misunderstanding the solution. It is what we refer to as an "AttachedBehavior". That is one method. I prefer to use System.Interactivity to capture standard events.
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
You can then use command wrappers (e.g. GalaSoft has an EventToCommand Wrapper or make your own) to fire a command in the ViewModel. Using Attached behaviors is also another way as was shown. I do understand your dillemna though and the reason being is you want to react business logic to UI logic but it is not set up in the framework for you. In comparison a button has a "Command" that you can bind to so it is there for you. You can however set up the logic has was shown. This does require adding DPs and appropriately attaching etc. It may seem like a lot of work but the thing is you can re-use the attached behavior anywhere. Therefore the advantage is you still kept your view and vm decoupled even if you had to use the UI effect in numerous places. [Edit] Yet another way to strap an event command using the same library.
I did this in a silverlight app because the DataGrid does not have a bindable SelectedItem. This was the easiest way IMO to pass the Selected item to the VM then.
Computers have been intelligent for a long time now. It just so happens that the program writers are about as effective as a room full of monkeys trying to crank out a copy of Hamlet.
-
I was reading through posts such as this one on MSDN[^], and I was wondering why in MVVM, we constantly try to save 10 lines of code in the .xaml.cs class by adding 100 lines in the viewmodel or helper classes. Can someone tell me the main benefit of taking such big hits in code size and readability to avoid putting code in the .xaml.cs file? I would think that even if you do regular event handling in the .xaml.cs file, it still follows the textbook MVVM pattern (view knows viewmodel, viewmodel knows model, no other knowledge allowed).
You can hand over the xaml file to the styling / UI team while your developers can continue to code and build the code behind for that file.
Build your own survey - http://www.factile.net
-
I was reading through posts such as this one on MSDN[^], and I was wondering why in MVVM, we constantly try to save 10 lines of code in the .xaml.cs class by adding 100 lines in the viewmodel or helper classes. Can someone tell me the main benefit of taking such big hits in code size and readability to avoid putting code in the .xaml.cs file? I would think that even if you do regular event handling in the .xaml.cs file, it still follows the textbook MVVM pattern (view knows viewmodel, viewmodel knows model, no other knowledge allowed).
-
I was reading through posts such as this one on MSDN[^], and I was wondering why in MVVM, we constantly try to save 10 lines of code in the .xaml.cs class by adding 100 lines in the viewmodel or helper classes. Can someone tell me the main benefit of taking such big hits in code size and readability to avoid putting code in the .xaml.cs file? I would think that even if you do regular event handling in the .xaml.cs file, it still follows the textbook MVVM pattern (view knows viewmodel, viewmodel knows model, no other knowledge allowed).
Well, for someone who has started WPF stuff, MVVM, Commanding & Data Binding looks bit confusing because of the numerous articles on the Internet. You might have visit some of those articles and come to this point where you would like to know more about the MVVM. When I had started the WPF had the same issue that you currently facing. The main advantages of the pure MVVM implementations are 1. Separation of concerns 2. Help out for Unit testing 3. Development can be carried out parallel 4. Tracing the changes/Impact and development is quite easy(this one is my favorite) Implementing pure MVVM(not writing a single code of line communicating VM or M) is bit time consuming as you have to spend lot of time searching for the mechanism for communication e.g. double click events that you mentioned in your question above. But believe me you will enjoy implementing it :-D To implement the Pure MVVM following points should be considered 1. Do not write single line of code communicating to the VM or Model 2. Though, View can contain the code lines related to GUI only. e.g. Adjusting some controls custom width/height on window size change, can go in main windows xaml.cs file as it has nothing to do with our VM and M. Its purely related to the View 3. If any controls needs to be referenced from the code behind, reference them from the App.xaml.cs file. App.xaml.cs, you can consider this as start up configuration. e.g. customizing the Title bar (showing the Title bar like Avast Antivirus check here) can go here. 4. Start the code from the App.xaml.cs file, configure your application here, like logging initialization, start up screen display, unhanded exception etc. 5. Inject the Model and View in the View model, this is best practices as view modes knows about view as well as model (know only at interfaces level) 6. Have a BaseVM class which will implement the INotifyPropertyChanged and derive your all Vm from this. This will help in eliminating repeated code Hope this will help you get going :-D Happy Coding :-D
-
Well, for someone who has started WPF stuff, MVVM, Commanding & Data Binding looks bit confusing because of the numerous articles on the Internet. You might have visit some of those articles and come to this point where you would like to know more about the MVVM. When I had started the WPF had the same issue that you currently facing. The main advantages of the pure MVVM implementations are 1. Separation of concerns 2. Help out for Unit testing 3. Development can be carried out parallel 4. Tracing the changes/Impact and development is quite easy(this one is my favorite) Implementing pure MVVM(not writing a single code of line communicating VM or M) is bit time consuming as you have to spend lot of time searching for the mechanism for communication e.g. double click events that you mentioned in your question above. But believe me you will enjoy implementing it :-D To implement the Pure MVVM following points should be considered 1. Do not write single line of code communicating to the VM or Model 2. Though, View can contain the code lines related to GUI only. e.g. Adjusting some controls custom width/height on window size change, can go in main windows xaml.cs file as it has nothing to do with our VM and M. Its purely related to the View 3. If any controls needs to be referenced from the code behind, reference them from the App.xaml.cs file. App.xaml.cs, you can consider this as start up configuration. e.g. customizing the Title bar (showing the Title bar like Avast Antivirus check here) can go here. 4. Start the code from the App.xaml.cs file, configure your application here, like logging initialization, start up screen display, unhanded exception etc. 5. Inject the Model and View in the View model, this is best practices as view modes knows about view as well as model (know only at interfaces level) 6. Have a BaseVM class which will implement the INotifyPropertyChanged and derive your all Vm from this. This will help in eliminating repeated code Hope this will help you get going :-D Happy Coding :-D
The problem I have with MVVM is it is very difficult to implement multiple usercontrols on the same form. I like to have my ribbonbar as one user control, a sidepanel treeview control as another usercontrol, a tabcontrol as another usercontrol, and a statusbar of course as another usercontrol. I generally have a mainform that I place these on using and etc. I've tried using caliburn micro to no avail as it will not display my controls even if I have no errors.