I am making a WPF Datagrid with lots of related columns. When you change X, Y should be X + Z. Etc. My first idea was to do this in the ViewModel properties with INotifyPropertyChanged. But I see that this also can be done with WPF triggers.
IMHO
If I do it with ViewModel/INotifyPropertyChanged there will be a problem with the first time initializing, where you do not want these rules to execute. I guess I could come around this by setting the private variables in a constructor.
The WPF trigger solution seems to be more complex and much more difficult to test.
Question
Are there any advantages letting WPF triggers do the job?
You've asked a bit of a subjective question here without much possibility of a definitive answer. However, I'm going to give it a try.
In my opinion, I would always manipulate data in the view model, for two main reasons:
Data manipulation = business rules and that belongs in the view model and not the view
You have access to every property of the data item(s) and every method in .NET in the view model, but access to very little in a Trigger.
I hope that helps in some small way.
Related
Let's imagine a very simple UI, where there's a list of checkboxes. When you click on any of them:
1) if it's not selected, it should create a workspace with this checkbox name (and more logic then is available in that workspace, but that's irrelevant to the question). The checkbox naturally then becomes selected;
2) If it's already selected, it should turn unselected and should destroy the associated workspace.
The straightaway form of implementing this is to have the View look at the state of the clicked checkbox and depending on being already selected or not do a viewModel.createWorkpace() or viewModel.destroyWorkspace(). But then that means that this logic is in the View -- I get the impression it'd be better to have it in the ViewModel.
I've read that the ViewModel for diverse reasons should not know the View. But one thing is not having a physical dependency to the View (an object reference, for instance) and another completely different is not even being aware that the View may have checkboxes, as in this example.
It gives me the impression that actually there's really not big of a point in making the View and ViewModel that much different, and in fact, the closer the ViewModel is to the View, the easier it is to bind data between the View and ViewModel.
How should I deal with this situation and why?
Thanks
The idea is to decouple the view and viewmodel.
You should be able to instantiate the viewmodel separately.
The primary reason for this is not some vague neatness or something.
The primary reason is so you can easily exercise tests on your code by instantiating a discrete class.
The view should do view things which are related to displaying data and allowing the user to interact.
The viewmodel should have the code that acts on those interactions and presents data to the view.
This does not mean the view should have no code at all.
If there is code, however, it should be view specific.
It's a good idea to use re-usable code such as behaviours.
Because then you can manually test these and prove they work. Then re-use your proven code.
Similarly with converters, validators etc.
All code.
All used in views.
I suppose it is theoretically possible to write an app which has no converters or validators or behaviours. I've never seen a serious business app didn't have all three though.
It is less important that the view knows nothing about the viewmodel than the reverse.
You're not going to instantiate the view to exercise tests unless you also have a viewmodel instantiated for it.
That doesn't mean you should just bung all your code into code behind though.
Why is that exactly?
Because the god of MVVM will strike you down with his lightning bolts?
Nope.
Because this will make future development easier?
Well it might, but not usually so much you'd notice.
Why then?
Because instantiating a view with it's controls is very slow.
They unavoidably have a lot of dependencies you can't mock.
It is likely to depend on resource in the application, so you'd have to instantiate an application and merge resource dictionaries.
Views often depend on swathes of libraries, pictures, usercontrols etc etc.
None of which you can mock.
So you need everything.
By the time you automate instantiating everything in some test runner and iron out clicking on buttons etc...
Your head will be hurting and you'll find those 2000 test you're theoretically wanting to run in a couple of seconds every 10 minutes take much longer than that couple of seconds.
You can't do "proper" TDD if you instantiate views in tests.
To answer your workspace checkbox question.
It depends on what a workspace is really.
A common pattern would be to initiate code in the setter of a viewmodel property bound to the ischecked property of each checkbox.
That might be in a viewmodel presented per checkbox which had the name of the workspace, it's type or whatever is required to do it's check-uncheck stuff.
Each would hold some sort of reference to these things it's creating so it can dispose them or whatever when that ischecked value becomes false.
I have been downloading a lot of example code to help me gain a better understanding of MVVM within silverlight.
One of the things I have noticed is an inconsistency within the sample code I have downloaded. Some for example implement INotifyPropertyChanged on the viewmodels, where others implement it on the Model.
Which is the preferred way of handling property changes, should it be handled at the model level or the viewmodel level?
Handling (Notifying) property changes in the viewmodel would seem more natural if this is to update the item that's being displayed in the view by databinding.
One of the reasons for having a viewmodel in the first place is that it holds the data from the model in such a way that it's easy for the view to bind to it.
So, if the main reason for your INotifyPropertyChange in is to update the item which is bound in the view, you should update it in the viewmodel.
I typically use DependencyProperty instead of INotifyPropertyChanged, but the idea is the same.
Their purpose is to notify the view controls, they are bound to, that they have changed so the view can update. This implies a weak connection between the view and whatever holds the property or object. In MVVM, the view should never have any link to the model because of separation of concerns.
I will often have physically force this by creating a separate project for each of the view, viewmodel, and model. So, the answer to your question is that the INotifyPropertyChanged should be implemented at the viewmodel level because the view should never touch anything from the model level. Having said this, MVVM is just a coding paradigm to make the programmers job easier, so there could be reasons to implement it differently if it means making your job easier and it doesn't having any negative consequences.
I'm looking for a simple way to link a view to a viewmodel and then to Entity Framework through databinding.
Can someout out there give me some pointers. What I'm looking for is a very simple implementation that would allow the view to automatically list all the contents of for example a one field table and for changes in the view to be propogated back to the database through EF.
AAfter spending a long time looking I'm still searching for a way to do this and any help would be very much appreciated.
Thanks,
Technically using a ViewModel means you don't actually bind to your entities. Your ViewModel classes should have everything on them that is needed by the view (and yes, this can cause what feels like duplication, but it's for the greater good), and therefore you don't even have this problem.
You can ease the pain of duplication by implementing something like AutoMapper to avoid the legwork of "left to right" coding where you're just copying properties across.
If you are binding a list, consider having an EmployeeListViewModel that has a property of type IList<EmployeeViewModel> on it, so that you're still not binding your entities directly to the view. This is useful because you can then reuse that EmployeeViewModel for a single-record detail view.
I often hear a Model must be wrapped by a ViewModel that the View is not coupled to the Model/not aware of it.
With MVC it is common to bind the View to the Model... nobody complains so what ?
I am frightened of creating all that wrappers and doing nearly only duplicating property stuff.
In some cases you don't need to, just as you don't need properties in many cases but can get away with public fields.
But your model should mirror the domain structure and logic, while a view model mirrors the UI structure and logic. At least, as far as I understood it. Those two are not necessarily the same and each one can change independently from the other.
You should always apply a pattern to your individual problem, and modify it in areas where it does not apply. Just because the pattern implies the usage of a view-model, doesn't mean you necessarily need a view-model in every scenario. In the case that your model exposes all of the needed properties and no further abstraction is needed, maybe a view-model is unnecessary.
However, in many cases the view-model will eventually be of great use and far easier to maintain than adding extra properties to the model. Consider this carefully before binding directly to the model.
The ViewModel is used to only pass the data that you really need to a view.
When you use the model, instead of the viewmodel it is possible that you use data that came directly from the database.
When using the model the wrong way, it is possible to edit data in the database that you don't want to edit.
It is safer to use a ViewModel.
One point which didn't seem to come up (directly) yet is that ViewModel can easily support data that should never even be in the model such as the text typed in the search text box or selected list items in case these values are needed in commands or further data bindings and passing them as parameters every time seems like too much trouble.
But as stated already, if you are confident that all the data you need is already available in the Model, go ahead and do away with the ViewModel.
One common scenario where ViewModels come in very handy is when Enum values should be displayed. In my eyes, a ViewModel is the perfect place to convert Enum values to user-friendly representations. You could even introduce a localization step in your ViewModel.
Furthermore, ViewModels can simplify some other scenarios. However, as you said, they can also duplicate a lot of code. That said, you could create a ViewModel with a Model property which allows to bind directly to the properties of the Model class. Now if you later realize that you need some conversion step, you can still add that property to the ViewModel and bind to that property.
But I think in most cases it makes sense to use a ViewModel from the beginning because it might be hard to introduce it in a later development stage.
There is no problem binding directly to a Model from your View where possible.
What you will find though is very quickly you run into a situation where you need to model things your view needs that aren't in your Model.
Given you never want to corrupt your Model with View concerns, you are left with no choice but to create a ViewModel.
It depends on may indicators: e.g. if your model is provided by EF there's no point in exposing it to your View - why the heck the View would need all model's method/properties and tons of stuff (not mentioning data security) But if your model is really simple and you feel, that you're not going to expand/change it much by and VM, there's nothing on the way to use it just like that :)
You might as well ask, "What's wrong with putting all the functionality of my program into one giant class?" On the one hand, there's nothing wrong; it can be made to work. On the other hand, everything is wrong: if your program is one big ball of wire, you have to straighten all of it out in order to change any of it.
Look at a Windows Forms programmer written by a beginner. You'll find all of the business logic in the buttons' Click event handlers. What's wrong with that? Don't you want that logic to be executed when the user clicks the button?
This is essentially what you're proposing doing within the world of WPF. Will it work? Sure. For trivial projects, it may even work well. You're accumulating technical debt, though, and when the time comes, you'll have to pay it off by refactoring your code into something manageable.
In my WPF MVVM application my model is a complex tree of Model objects wich constantly changes at runtime. Model instances come and go at runtime, change their position within the tree and of course change their many properties. My View is almost a one-to-one visual representation of that tree. Every Model instance is in 80% of the cases also a node in the tree.
My question is now how I would design the ViewModel around this? My problem is that there are quite a lot of different Model types with each quite a lot of properties. If I understood MVVM corretcly the view should not communicate with the Model directly so this would mean that I would have to create a ViewModel type for each Model type and have to rewrap each property of the Model type in the ViewModel.
Also the ViewModel would need to "bind" to the propertychanges of the Model to pass it along to the view (using wpf datatbinding). I would need some factory that creates and introduces a ViewModel instance for each Model that appears anew and I would habe to dispose each ViewModel instance when the corresponding Model disappears. I end up keeping track of all instances I created. It is unbelievable how much bloat code is generated dues to this double wrapping.
Is this really a good approach? Each entity and each property more ore less exists twice and I have a lot of extra code keeping Model and View in sync. How do you handle this? Is there a more clever way to solve this?
Does anyone have a reference/sample implementation for this that does it better than I do?
I think you may run into trap of paradigm if you follow this path. MVVM is nothing more than a pattern, which simplifies development in WPF world. If it doesn't - don't use it or revise your approach. I wouldn't spend 80% of my time just to check the "Using MVVM" field.
Now back to your question. Correct me if I'm wrong, but it sounds like you are looking at MVVM from opposite direction: you don't need Model to ViewModel one-to-one correspondence. Usually you create ViewModels based on your View first, and only then on a Model.
Generally you look on a screen mockup from graphic designers, and create corresponding ViewModel, which takes all necessary fields from the Model, wraps/modify/format/combine them to make View development as easy as possible.
You said that your View is almost one-to-one visual representation of the Model. In this case it may have sense to create a very simple ViewModel which exposes root object of your model-tree, and let View consume model directly via that property. Then if you need some View customizations or commands processing you can delegate that to ViewModel.
Sorry for very vague answer. Maybe if you ask more specific question we could dispel the confusion :)...