I'm trying to learn the MVVM model by creating an UWP project. From what I've gathered, ViewModel is supposed to be independent from the actual View (portable?). I just want to clarify if what I understand is right.
Say I have a SplitView:
<Grid>
...
<Button Click="ActivateRelativePanel Content="CLICK!"/>
<SplitView>
<SplitView.Pane>
...
</SplitView.Pane>
<SplitView.Content>
<Frame Name="MyFrame"/>
</SplitView.Content>
</SplitView>
</Grid>
Is it right to change the Open/Closed status (SandwitchSplitMenu.IsPaneOpen = !SandwitchSplitMenu.IsPaneOpen;) of the SplitView in VM or xaml.cs, since this is a view specific thing? From what I understand so far, this should be inside a xaml.cs file, since it's a view specific thing, but a friend of mine told me that I should use xaml.cs file as less as possible when relying on MVVM.
While I'm at it, should the Frame be Navigated (MyFrame.Navigate(typeof(SomePage));) through the VM or xaml.cs? The frame is also a view-specific thing.
I know that loaded data from the models should be done by binding, through VM, but I'm interested as to what is supposed to be inside a VM and what is supposed to be inside a xaml.cs file.
Also, any other good UWP MVVM tutorial guide or anything is more than welcome!
Well, several things:
MVVM pattern lets you decouple your view and your business logic. There's many advantages, and one of them is testing. You can test your view model without thinking of your view because it is made to be independent (your view model does not have any consciousness of a view). Separation of concerns is also a great practice to get your code organized.
Starting from this, you should place in your code-behind the minimum code possible. Acceptable code would be code which manipulates UI element exclusively, like sizing, managing animations, ... All which is related to data and other stuff should go directly into your view model.
Navigation should also be handled from view models, because logic takes place there, and navigation relies on logic.
For your IsOpenPane case, it's subject to debate. It manipulates the UI element but I suspect it's manipulated from a business logic. So, personally, I would declare a public property in your view model which you bind to the xaml property IsPaneOpen.
Regarding UWP MVVM guide, you should see MVVM: Tutorial from start to finish?.
It is not exclusively for UWP and resources are quite old, but the concepts are the same (only some XAML elements are differents, but pattern and spirit are exactly the same).
But above all: https://mva.microsoft.com/search/SearchResults.aspx?q=uwp
Microsoft MVA is really great!
Once you'll be at ease with XAML and MVVM, see https://dev.windows.com/en-us/design. It's the official Microsoft documentation about UWP and design, where you can grasp key concepts like responsive design techniques (which is specific to UWP, and brings tools which make a universal app usable by any display, from IoT to TV). It's of course well written and well structured.
Related
I have some doubts in viewmodel pattern. My doubt is about, why we don't use UI elements in viewmodel. If we use UI elements in viewmodel what will happen like any performance issue?. Please give any suggestion.
You do not use UIElements in ViewModels, since the MVVM principle defines UIElements to reside in the View. The correct placement of UIElements, is defined by John Gossman, in the article Introduction to Model/View/ViewModel pattern for building WPF apps:
The View in Model/View/ViewModel consists of the visual elements, the buttons, windows, graphics and more complex controls of a GUI.
You do not use UIElements in the ViewModel of an MVVM application, for at least two reasons:
When later porting the application to another UI framework, it is much easier if all UI related code is just in one module, namely the View. Porting would be much harder if UI code would be spread across the View and the ViewModel.
Unit testing is much easier if all UI related code is just in the View.
The latter reason, of course, is the most important, for most developers. Josh Smith, the father of WPF-MVVM puts it like this in his article Patterns - WPF Apps With The Model-View-ViewModel Design Pattern:
If you can write unit tests for the ViewModel without creating any UI objects, you can also completely skin the ViewModel because it has no dependencies on specific visual elements.
UIElements are troublesome for unit tests, because WPF UIElements need a layout-measure-render loop for working correctly. In unit tests, however, you usually do not have such a loop.
If the code-behind for the View is meant to consist of nothing but the constructor with the InitializeComponent() call, why not just use DataContext="{Binding RelativeSource={RelativeSource Self}}" and use the view itself as a view model?
I get that this technically violates the Single Responsibility Principle, but since the XAML and code-behind are defined independently from each other, it doesn't cause the usual mess. Having separate view models for everything causes more mess to the file structure.
ViewModel describes view state. For testing and reusing purposes it must be UI independent.
Benefits:
You can cover ViewModel by unit tests and you haven't to refer UI
classes in test
You can reuse your ViewModel on other UI targets:
console app, WinForms App, UWP app, Xamarin iOS/Android App, no
display IoT project. You'll need to write only view for new target platform.
Sometimes even in WPF and MVVM you have to write some code behind for View-only purpose because it may be much more simpler, readable and reliable then create some new entity for that. And you'll get mess if you have also ViewModel in code behind.
Recently i got explained that MVVM can only be done "the right way" if i use DataTemplates. Is this truely the case?
I'd say its a good idea to use DataTemplates if you want highly reusable "Views".
But if i am going to develop an application that has, say, five to ten different pages, and there is very little to none reuse of specific controls (like the "Person" view is only used once, and its highly likely that this requirement doenst change), why cant i simply create a usercontrol and put that directly into the code?
Am i missing some important core principle of MVVM here?
Main selling point of MVVM is separation of View from the ViewModel (so that VM doesnt know about View) by using powerful Binding feature of WPF.
DataTemplates are a just another feature which allows you to represent data in different way. As you have said, if you dont have reusable DataTemplate then dont create one, even if you do make sure it resides in the View's Resources, you can share it wider group if you wanted do.
using UserControl can be useful where you need to do something extra (apart from simple representing data), for example, some complex validation or extra commands/buttons
I dont think MVVM and DataTemplates are related in the same context.
There is no special needing for DataTemplate, you have a view and a viewmodel that cooperates with databindings and events. The MVVM goal in WPF is to remove the code from the view to achieve a real presentation only view, and not a messy code behind store. Having the ViewModel agnostic from the view is another goal, even if not always achieved.
My name is Jesús from Spain, I'm a .NET developer and I just discovered this great web few days ago.
I have some questions about the MVVM pattern and I will be glad if you can answer them.
I started using WPF three months ago and I've learned the MVP pattern.
MVP is so good because you can structure the application so well.
I started seeing MVVM everywhere, but everyone is using the pattern by his own method.
Every blogger is talking about MVVM in their WPF's blogs but every implementation is distinct.
I'm focused now with the implementations that use the MVVM toolkit on CodePlex, but I have questions and I can't find too much information.
I think that MVVM is a variation of MVP.
With MVP every view has a presenter that does the view's job.
In MVVM it's the same thing but using commands whenever you can.
I also saw that if you need an event, it's like with MVP; delegating the event to the presenter / View-Model, that is if it's not a job for the view (such as updating the UI).
On the other hand, the View-Model doesn't has a View reference so I have to play harder with data-bindings.
You have to use the DelegateCommands (that are the same thing as RelayCommands, right?).
Uhm... more questions... Is it safe to use the same View-Model with two views / user-controls?
Oh... I ran into a problem yesterday when I was playing MVVM.
I created a CommandReference of my command for the key-binding thing and I assigned this reference to the command property of my button, well, the CanExecuted worked the first time but it didn't update the IsEnabled property when the CanExecuted was true. I fixed it by binding the command directly to the button and not using the reference. The question is: Why some code is linking the reference to the objects and why other code is binding the command directly?
What things related with MVVM should I learn? (I saw something called attached behaviors yesterday but I don't know what is that).
I'm rewriting a note tacking app that I developed using MVP but now with the MVVM. I will replace the events with commands (using the DelegateCommand), eliminate the views references on the View-Model and I think that's all because the examples that I saw of MVVM is much like MVP.
Well, I will appreciate if you point me to all the misunderstandings that I have with this pattern.
Thank you and in the future I will help the next MVVM novices :)
Wow, I'm going to try to answer as many of your questions, that don't involve a specific technology or framework, as possible... sorry if I miss some (bullet points would help)
MVVM is not necessarily a variation of MVP. MVP itself is an ambiguous, loaded term. Martin Fowler did it justice by splitting it into two patterns. MVVM stands on its own, but shares some concepts with the MVP patterns. Like all UI patterns, it seeks to separate view logic from business logic as much as possible. What the MVVM does that is different from MVP is it creates a model purely for the purpose of presentation (or a presentation model). This is different than how MVP patterns solve the separation problem.
Passive View - With the passive view, the view never sees the model.
Supervising Controller - MVVM is much closer to the Supervising Controller pattern than to the Passive View. The only real difference here could be that the MVVM explicitly creates a model just for the view (hence the term "View Model")
The ViewModel doesn't have a reference to the view, because it serves as a model for the data of the view. This is an appropriate abstraction. If it also referenced the view, you would have a two-way dependency which would create additional coupling. Also, the ViewModel itself doesn't have a real reason to be aware of the View. Its only job is to abstract the model (the actual business model) from the view.
DelegateCommands vs. RelayCommands - I believe you're getting technology specific here, so I can't really answer that one well.
You should not design a ViewModel for more than one view. This only creates coplexity inasmuch as if you change a view, you will have to investigate which ViewModels might be affected and change those. This could possibly lead to a cascade effect. Your behavior should be in the business model, not the ViewModel, so the ViewModel need only contain translation and event handling logic.
It would be a good idea, however, to have a 1:1 ratio of ViewModel to UserControl, since UserControls are supposed to be able to act as autonomous units on your screen.
As for the other technology specific questions, sorry, I have no answer. I can suggest, however, that you carefully read the links I included for the Passive View, Supervising Controller, and Presentation Model. The provide some context to UI patterns, and are technology neutral.
It's important to keep in mind that, while MVVM is suited to solving problems posed by adopting WPF, it is not a technology specific pattern. If you dive too deeply into a specific implementation without understanding the underlying philosophy, you could make some very big mistakes early on, and only discover them after it's too late. Unfortunately, MVVM is not a well documented pattern, and you are right when you stated that everyone has their own idea of what it is.
It's not a revolutionary pattern (it has been around for years under different names), but the data binding of WPF makes it a viable solution now, and so it's enjoying newfound popularity. It's a good pattern, but it's not doctrine. Approach every "dictate" you're faced with with the appropriate amount of skepticism.
EDIT
#micahtan is right when stating that data bind is a very important piece in WPF. I stated that WPF's data binding enables the MVVM solution, but the binding itself is very powerful, which is why adoption of MVVM is growing faster than the literature surrounding it.
You don't actually have to use the RelayCommand. All you really need to do is implement the ICommand interface on an object. In the SoapBox Core framework I defined an interface called ICommandControl and all button ViewModels, etc. implement that. There's also an AbstractCommandControl class you can derive from to implement it.
The more I learn about WPF and XAML, the more I realize that you can do pretty much all of your GUI initialization and event handling glue in either XAML or in code (say C# code or VB.Net code).
My question is to those who have been working on WPF for longer and ideally those who have shipped apps with it -- where did you find was the best place to 'draw the line' between XAML and code? Did you use XAML wherever you could? Only where interfacing with non-coding UI designers?
Any tips in this area would be extremely helpful to myself and other coders who are just getting into WPF programming and are kind of paralyzed by all the choices we can make!
One thing that I would look at is the model-view-view model pattern. It is a very elegant pattern which naturally separates everything into nice buckets ... including your xaml.
For example, it helps you keep a clear boundary between the developer and the designer and even allows for test driven development.
There is a whole bunch of info out there on it, but I would start with John Gossman's blog posts:
http://blogs.msdn.com/johngossman/archive/2005/10/08/478683.aspx
http://blogs.msdn.com/johngossman/archive/2005/10/09/478894.aspx
http://blogs.msdn.com/johngossman/archive/2006/02/26/539598.aspx
http://blogs.msdn.com/johngossman/archive/2006/02/27/540304.aspx
http://blogs.msdn.com/johngossman/archive/2006/03/04/543695.aspx
http://blogs.msdn.com/johngossman/archive/2006/04/13/576163.aspx
Update:
Just want to point people to another StackOverflow post with lots of good info on M-V-VM in it.
One tip is to not declare event handlers in XAML. Instead, name your elements and attach events handlers in the code-behind. That helps keep a clean separation between the designer and developer.
As others have suggested, try following the Model-View-ViewModel pattern. However, it's OK to put stuff in the codebehind! The rule is that if it's "View" related, you put it in the Xaml or the codebehind (whichever is more convenient for you). If it's more business logic related to how the user interacts with the system, then it belongs in the ViewModel. If it's just business logic not concerned with interaction, it belongs in the Model.
Examples of each would be:
Model: defines a property called ModifiedDate that stores the last time it was modified.
ViewModel: converts the ModifiedDate into an enumeration property called ModifiedAge, based on when it was modified: Yesterday, In the Last Week, In the Last Month, In the Last Year, etc.
View: converts the ModifiedAge property to a background color where more recently accessed data is highlighted bright yellow, and less recently accessed data is more of a beige-khaki-gray that your designer insists is called "Meadow Lark Lilly Flowerpot".
Another tip is to separate XAML into functional and aesthetic. Developers would typically work in the functional XAML whilst designers care primarily about the aesthetic. This keeps the functional XAML very easy to grok, which is important because developers often need to edit such XAML. Aesthetic XAML is typically edited by designers using tools, so its neatness and verbosity is less of an issue.
I did a bit of a blog post on this a while ago here.
Don't lose sight of the fact that XAML is code. It's declarative and all that, but it's still a programming language. In fact, it goes through a conversion to C# or Visual Basic before it's turned into IL for the .NET compiler to chew on.
I'll echo Scott Whitlock's comment: MVVM is a great way to separate concerns and focus on architectural details. It's really, really OK to put stuff in your code-behind, especially the stuff he describes. If you don't have a requirement to separate designer from developer, then adapt the MVVM pattern to your specific needs; don't try to force yourself to be pure or idealistic about it.
It's also perfectly OK to put calls to your ViewModel's methods right in the View code behind, if you don't need the flexibility of commanding with ICommand classes. Or if you know the View you're making will always be bound to the ViewModel class you're making. Or you could take things a step further, define an interface for your ViewModel, and bind only to implementations of that interface. Then you can still swap out the ViewModel whenever you want.
Stuff like that.
When you follow a proper pattern like Mode-View-ViewModel you will get opportunity to do more on XAML side and less on code behind. Maximize the usage of RoutedEvents and Commands in WPF code.
When building UserControls I try to Xamlize as much as possible.
One tip I found in the field is that creating ControlTemplate and DataTemplates by hand is really a pain in the ***... I always write those in XAML....
I would say use as much xaml possible, using Binding, commands, styles, templates etc. I had to support functionality of saving and loading templates using XAMLReader/XAMLWriter and it more easier for controls having more xaml.