I'm creating a windows 8 application (but I suspect that any one using Xaml can help me). It basically boils down to: a page with a list of products on it, clicking on a product opens a details page.
In my composition root I resolve the view model for the first page, and set the data context appropriately, but I'm not sure what the best practice is for passing a view model to page 2 when the user selects a product.
As far as I can tell I have the following options:-
The first viewmodel requires an abstract factory capable of creating
a view model for page 2 with a .create(product) method, this would be passed in to the first view models constructor
Have the second view model implement an interface with an product property allowing me to use property injection, and pass the second view model as a parameter to the first viewmodel.
Create a service locator which I know is considered by many to be an anti-pattern.
I'm at a bit of a loss, but I suspect the abstract factory is the right way to go, I want to get this right as the object graph is actually this (product->Step->Instruction), so any re-work could take quite a bit of time, but it basically means that my view model if I went down the abstract factory route would take three abstract factories, and the service for getting the initial list of products (and then is this a code smell given how many parameter it has!).
In the situation where you want to resolve the view-model in runtime (from code) factory is the way to go.
To make it easier I would also consider using some DI framework. I believe there won't be many of them for WinRT but autofac is supposed to work with metro.
Dependency Injection might be the way to do it if you are building something big. Personally I usually just pass the parameters in the Navigate() call and initialize the view model using these parameters in the OnNavigatedTo handler.
Related
Suppose upon a button click in the View, the ViewModel calls an asynchronous, long and tough calculation on the Model (with Model being business logic and data, as per Wikipedia). During this calculation the Model is spitting out one calculation result after the other (which are of a different kind, it's not like an ObservableCollection is useful here) and the View is supposed to display them the moment these part-results are ready.
How can it do that?
Via an EventAggregator? Caliburn Micro has one but that would mean I had to reference Caliburn Micro in my business logic - this can't be right, can it?
Via INPC? I have the impression that wherever I implement INPC, that class is going to be exposed to be bound to. I obviously wouldn't want a class with business logic exposed to the View just so I can bind to some of it's properties. So I'd need an indirection with a separate class (implementing INPC) whose properties I set from the business logic that the View can bind to. Now what I have done feels like creating a ViewModel that the model is tied to. - this can't be right either! (Not exposing it, but wrapping it with a ViewModel subscribing to PropertyChanged feels like a pretty severe violation of DRY)
So I guess I need to use plain old events? Having read Mark Seemans book and blog on DI I have the impression this is wrong too. Since subscribing to an event in the constructor is wrong. His suggestion is to reverse the logic and let the DI container inject an IObserver<> into the business model class, which will call Next() on it. That would mean the ViewModel will implement potentially quite a few IObserver<> interfaces? Is that it?
I need a bit of guidance here, thanks!
I'm over-thinking this and getting myself into a muddle but can't clear my head.
I'm new at WPF and I'm trying to get familiar with MVVM. I understand the theory. I need a view, a model and another model (called the view-model).
However, what happens if my model is constructed by a parameter of the View's constructor.
So, assuming I have a totally empty project, the only thing is I've an overloaded MainWindow constructor which takes the model:
public MainWindow(Logging.Logger logFile)
{
InitializeComponent();
this.DataContext = logFile;
}
The Model is the logFile. Can I still implement the MVVM when I don't have a separate Model class?
Any thoughts would be appreciated.
You're overthinking this.
There are several components to MVVM:
View:
The view provides a, well, view on the data. The view gets its data from a viewmodel
ViewModel:
The viewmodel is there to organise your data so that you can organise one or more sources of data into a coherent structure that can be viewed. The viewmodel may also perform basic validation. The ViewModel has no understanding of the UI so should not contain references to controls, Visibility, etc. A viewmodel gets its data from services.
Services:
Services provide data from external sources. These can be WCF, web services, MQ, etc (you get the idea). The data the service returns may need to be shaped so that it can be displayed in the UI. To do this you would take the raw data from the service and convert it to one or more Model objects.
Model:
A model object is an object that has been created so that it can be easily displayed/work with the UI.
You may find that you don't need to shape your data coming from your services (lucky you), in which case there's no need to create model objects. You may also decided that you don't want your services talking directly to your viewmodels but instead what to have them get their data via a "mediator" object. That's also good in some situations (usually when you're receiving a continuous stream of data from a source/multiple sources).
MVVM is a bit like porridge: there are lots of potential garnishes you can add, but you don't necessarily need to add them all. Or want to.
Does this help?
Edit: just stumbled on this: a more in-depth expression of what MVVM is:Mvvm Standardisation. This may also be useful
The Model is something the ViewModel will know about but not the View. If you need to present info about a Logger, you can certainly have a LoggerViewModel that knows about a Logger, and in turn the View winds up getting to know about the ViewModel. There are several ways to do that, and setting the DC in the view constructor is one of them.
After that basic understanding of who knows about who, what really makes the MVVM architecture pattern, IMO, is that ViewModel communicates to the View via databinding. Nothing more and nothing less. Lots of goodies come out of this, but that is the crux of it that makes it different than other separation of concerns patterns (like Presentation Model, MVP, etc)
That said, you need to get a feel for it by working through some sample projects. Asking questions here on SO is fantastic when you get stuck on something, but you must realize your question here is a bit fuzzy at best. Also, unless you are really looking to present logging info in your view, logging is not an MVVM concern. Its interesting alright but not MVVM.
Google Josh Smith's MVVM demo on MSDN for a perfectly meaty yet approachable beginning sort of project. And ask more questions or refine the one here as they come up!
HTH,
Berryl
forget the view! at least at the beginning ;)
try to think about what you want and what you need. what i understand is that you wanna handle a logfile. so you need a viewmodel for that.
public class LoggerViewmodel{}
you can put the logfile as a parameter to the vm ctor. now you have to think about what you wanna do with your logfile? for everything you want create a property (LastModified, LastRow, whatever) on your viewmodel.
btw there a two different ways to do mvvm, first is view first and the other is viewmodel first. i do both in my projects and take the appraoch wich fits better (viewmodel first the most time ;)) to my needs.
pls edit your questions and add what you wanna do with your logfile, then we can give you a better answer.
edit:
Can I still implement the MVVM when I don't have a separate Model class?
to answer your question the short way - yes you can. you have to seperate the view and viewmodel and use binding to bind the view to the datacontext(viewmodel).
Sorry if this is a duplicate, It's not so much 'What is MVVM' though, but rather, 'Is this MVVM', I've read quite a bit, and think I've got a basic understanding of what it is, I've got my own 'one-liner', as such, on how I interpret it, but want to make sure it's correct before I firmly ingrain it in my head,
Essentially; The Model is pure data - no methods, there is one ViewModel per Model, it holds a reference to the Model - it performs all changes to the Models data and finally the View will hold one (or more) ViewModel reference(s) and format & display the data provided by the ViewModel.
(Not after links to tutorials, blogs etc, just a yes, or no with tweaks will be fine, as I'll have to re-read everything again anyway if not :) )
Not completely - at least, not as I would completely define it.
The Model does not have to be pure data. The model is the portion of your application that is completely domain specific, and has no "presentation related" information.
This will typically include all of the domain specific data, but also potentially methods that are pure business logic, and data access, etc. Anything specific to the business logic and processes, and not part of the "display", is part of the model.
Also, although "one ViewModel per Model" is the most common form of working, there are times when you may expose a "model" class through multiple ViewModels. This can be useful, for example, if you are trying to expose only part of a model to your designer, as it allows you to make a smaller ViewModel class. The ViewModel adapts the model for work with the View - if the entire Model is not required, this adapter can be made smaller (and more easily testable, maintainable, etc) by only working with the portion required.
Personally, I prefer to think in terms of "one ViewModel per View", as the ViewModel can adapt one or more models in order to work appropriately with a given View, but even then, sometimes it's helpful to swap out a ViewModel within the same View in order to change content.
Close, but not quite. Here are some points that are are different than yours:
Models can have methods on them. They are not just data. They might have methods like "retrieve", "store", etc. Business logic code. View agnostic.
There is no restriction to how many ViewModels hold a reference to the Model. ViewModels encapsulate view-level behavior, so you may have many different sets of behavior for the same model. For example, one ViewModel might be a read-only transformation of a model item. Another might provide read/write form validation on the same model item.
There can be more than one ViewModel per view, based on the behavior you want. For example, you might include "premium content" behavior with one ViewModel and "free content" behavior with another ViewModel but maintain the same view.
Essentially, yes. Practically, not really. Best practice is always to reduce dependencies and split up your responsibilities among classes on a 1:1 basis, but you'll find IRL situations where it isn't as easy to be a MVC purist.
I think the best attitude is to do your best, then document the rest. Don't sweat purity too much.
There is a lot of great information here, and I think that most of these answers are right. I don't think there is any 1 specific definition, nor is there 1 specific authority on this matter. Even microsoft does not really have clear definition on this.
The one item I would add which is not in the name of MVVM, but is common to all implementations of MVVM that I am familiar with. This is a Messaging or Notification system, which seems to always be linked as a platform for the ViewModel. Messaging just notifies the View Models when things change which may affect others. A good implementation of this in mind allows View Models and Views to both be agnostic about things they do not directly bind to by using generic notification messages.
The benefit of the entire pattern in my opinion is to make you application with modular, swappable parts with as little type-dependency as possible.
This is a real missing part in my mind, as it provides the same benefits / functions that you gain from separate controller logic in the MVC pattern.
That is pretty close. Except it is not correct to say that the Model is only pure data. It can and should contain methods for performing the various use cases against it.
Your understanding is wrong.
You can have several Models and all of them could have their own Views and then be a part of a single ViewModel.
Example:
You have the Models: Product, Customer
Each of them have their own View represented as a Custom Control
And you have a ViewModel which combines all your models and finally on the window of your app you combine all together your Views which talk to your Models via your ViewModel
Think of it like this. The Model is your system, the meat and veg of what the system does. The only considerations it has is how to do it's job, not how it is going to be used. It exposes events, attributes and methods defined at the system level, but it has no concept of what will be pressing it's buttons (or if it even has buttons!). It does not try to format data to a more user friendly format, it formats its data in a model friendly way.
The view model is the UX (user experience). It defines how you are going to use the system. It defines (through public commands and attributes) user orientated access into the system. It is the bridge that the user will use to enter the system. It binds onto the events of the model, and through it's commands, it will provide access into the models functionality.
It should handle validation, (is that age a sensible age?) retrieve data, converting and caching of records whilst they are being displayed. So, for example, you're looking at a patient record, the viewmodel gets the data from the model, and caches it internally, then publishes this to the view. What happens if the model announces an update to that data? Throw the cached data away? what if you've edited it? This is all up to you, and this behavior should be defined in the view model.
The view model is a "contract" of what functionality and data is exposed to the user (through the view). The view model has no concept of HOW it is going to be displayed or interacted with. Commands should be named at a functional level, such as RefreshList, NOT MouseClickHandler.
Finally, the View. This is simply a visible representation of what is in the view model. Buttons and menus etc bind onto commands. Fields bind onto attributes and will update automatically through the magic of binding.
If you ever see yourself doing : "text1.text = value" you're doing it wrong. If you ever find yourself writing a command handler that says "my.ViewModel.SomeCommand" you're doing it wrong.
Guess we have simple model, e.g. let it be a Person { Name, Age }.
Now we want to display a list of persons.
Persons are read-only
We don't need to edit them
We don't need any additional stuff like presentation properties, etc.
Now question is if it is a good practice do not create PersonViewModel class that will probably be a copy of model class or will delegate all its properties? Is it a good idea to simply bind listbox to list of persons, not to their view models? It looks DRY enough, but what about idea of MVVM?
I have no issue with bypassing the VM and using the M directly in the View. Sometimes the models are so small and static that loading them into a wrapping VM is wasteful.
I've created standalone ViewModels, but generally not standalone models. The reason for this is DataBinding -- most POCOs don't implement the INotifyPropertyChanged interface and adding them in to make them pseudo-Models seems to defeat the purpose of re-using a simple class AND respecting the MVVM pattern.
Now, if you KNOW you're never going to be editing them, it may not be a bad idea. A VM with simple property redirects seems a bit pointless to me.
As far as I'm concerned, if you implement INotifyPropertyChanged, then it becomes a ViewModel, and you can bind to it. :) When I wrote SoapBox Core which is all MVVM, I took the approach that everything is a ViewModel. The only Model objects were classes from third party libraries that I brought in and wrapped in a ViewModel of my own.
I wouldn’t create a ViewModel for the Person business object when the ViewModel doesn’t introduce new required functionality.
You might be interested that there is a second approach in the MVVM community: Create a ViewModel per View and not per Business Object.
Sample applications that follow this approach can be found on the WPF Application Framework (WAF) website.
If I have an object, say, a user class, with say First & Last Name properties what is a better way to populate it:
The PAGE instantiates the class and the PAGE calls the business layer to popualte the class. (In this case the class is essentially a container for data).
or
The class itself not only has the properties, but it also has a method to call the business layer, populate itself and return itself populated to the page.
I'd go for the former. I think it's cleaner, and that way your User class can stand on its own, even if the business layer changes.
Note, also, that the former would seem more conducive towards using a 3-tiered MVC architecture as well.
It really depends on what you are going to use that class for. Is it only ever going to be a container that you populate and use for display? Are you going to be modifying that data and using it to update your database?
Basically what you are looking at is the DAO/DTO set of functionality. In case #1 you are talking about a data transfer object (DTO) it's just a container for the data. In case #2 you are talking about a data access object (DAO) it's an object that understands how to persist your data and where to get it from.
What you are missing is a case #3 which is a business object that understands the business logic associated with your data. i.e. what permissions does my user have, what is my users position within the company (assuming a business user).
Unfortunately there is no one correct answer, it all depends on what you are trying to build.
I prefer the former. With the latter you end up forcing dependencies in the weirdest places.
I'd suggest reading up about the factory method and abstract factory patterns, with a view to delegating creation of the class to something other than the class or the page. Here's why:
The page is focused on page stuff - it only cares about something that holds a first and last name, not the type of class. Therefore, it shouldn't create the class, just ask for an implementation. The page only really cares about an interface, with maybe firstname and lastname properties, and maybe a save() method.
If the class knows about the specifics of the business layer, you have dependencies you don't need. To change the business layer, you'd have to change the class internals or change the page so it creates a different class. If you did that for many classes, changing the business layer would require many changes in the class and/or page layers.
I would have an abstract superclass for all the business objects implement a reloadData() method. It can be tested separately from the web environment, and the web environment does not depend on the data layer.
The way I look at it is you have to have separation of concerns. Testing is much easier too when you have less dependencies. I would use the first method.
What about if the object has a .Save() method that calls the Business.Save() method?
Perhaps this is mixing it up too much though.