I'm designing an MVVM framework and I need to know if my understanding of MVVM pattern is correct or not. My question is simple. How should I pass the ObservableCollection object between the VieModels? or shouldn't I?
I have a CustomerViewModel which has an ObservableCollection to hold a list of customers. I also have an InsertCustomerViewModel which is responsible for insertng new customer models in to that ObservableCollection. in the InsertCustomerViewModel I have a method called Insert() which is called everytime the user clicks on the Insert button.
What I'm doing so far is passing the ObsertvableCollection from CustomerViewModel to the constructor of the InsertCustmerViewModel and then in the Insert method I have Items.Add(newCustomer).
Is my implementation correct? or is there any better way to do the job?
I would pass the CustomerViewModel to the InsertCustomerViewModel and expose a property for the collection. That way you can use and modify that collection from InsertCustomerViewModel directly.
From my point of view InsertCustomerViewModel does not make any sense here. When user insert a customer it should only add in CustomerCollection Class which should be a Model for multiple ViewModels.
I think the idea should be share the same CustomerCollection model among the two ViewModels via some common instance.
Related
Where to properly implement INotifyPropertyChanged? In Model or ViewModel? And how do you do that having a 1-to-many relationship between two Models?
Normally you do implement this on property setter.
for more info check this link
How to: Implement Property Change Notification
Jitendra Aanadani,
I would add the implementation in your view-model , your model is suppose to be a simple class (poco). I don't really know what you mean by "pull a list of children" but in my opinion if you need to get some additional data you should have a repository or some kind of service class which will provide you that Data.
I hope i could help you.
So far I have yet to see the value of having models in WPF. All my ViewModels, by convention, have an associated Model. Each of these Models is a virtual clone of the their respective ViewModel. Both the ViewModel and Model classes implement INotifyPropertyChanged and the ViewModel just delegates everything to the Model anyway.
Why bother having Models then? Why can't I just move my Model logic up into the ViewModel and call it a day?
It seems rather redundant (that is, not DRY) to have MVVM, and just use VVM by default unless some special edge case demands a Model.
If using explicit model classes better supports unit testing, for example, or some other best practice, I can see the value.
The model is just the low level application data.
The view model is more specific.
It's like a window tapping into the data tailored for the view.
It also augments the model with details needed for the view. A good example is pagination.
A model can have more than one view model. These view models would offer different aspects of the data.
You can create a mashup of different data sources. A view model cleanly façades the models involved.
That means there is no 1:1 relationship between models and view models.
So, if you just display the low level data without a lot of additional logic, features, summaries, aggregations, filters, etc. you can do away with view models and just use the model directly. This seems to be the case with your project.
The model can be auto-generated (Entity Framework), or it might not be a specific class at all (think of a DataTable).
I assume that if you say "I don't use a model", you do in fact use a model, you just don't call it that way.
First of all, even in MVVM you can expose your Model directly in the VM and bind through it to the Model. {Binding MyModel.MyModelsProperty} where DataContext = ViewModel that way you don't have to necessarily wrap everything unless that is just your style to do so.
The ViewModel and Model have different responsibilities. For example, consider designing a file explorer with a tree view of folders. Each node in the tree view is a Directory/Folder. The directories are the models and they have properties related to the file system. The ViewModel may wrap or expose these properties for the TreeView nodes to display (For example the Name of the directory), but it also adds additional information such as "IsEditing" and "IsExpanded" to determine the state that the node is in.
You're just talking about one pattern in MVVM, actually there are more.
In Stateful viewmodel you don't actually delegate things to Models, Viewmodel itself maintains its state, so as you said in this pattern you can almost ignore the model as you can have state in VM itself.
To create isolation between business logic and presentation, data
should be removed from the view. The stateful view model pattern moves
data into the view model using XAML data binding. This allows the view
model to be tested without constructing a view, and it allows the view
to change with minimal impact on the business logic.
In Stateless viewmodel you delegate the calls to Model, which is what you're probably referring to.
Note that you don't necessarily implement INotifyPropertyChanged in Model. Just implementing it in VM is fine as long as you don't change the properties directly in Model.
So why do we need VM and Model? VM is for supporting view like providing Commands, etc and Model is just to hold the piece of data abstract the same.
If you think of it as an abstraction, let's say you need to build a screen to display a list of Employees and make a Selection, Search or Filter. Then we break it up in components. You will require:
An Employee class (Model)
An EmployeeManagementViewModel to prepare and present your list of Employees and manage state changes for your View (e.g. can contain a SelectedEmployee, Filter Search text, etc) to be used by your EmployeeManagementView
A list of Employees (Which will live in your EmployeeManagementViewModel)
Most likely you will already have an Employee class. If that's the case then you just need to expose that model in your EmployeeManagementViewModel as an ObservableCollection of Employees.
In case you don't already have an Employee class you may decide to create an EmployeeViewModel and add your Employee properties there like FirstName, LastName, etc.
Technically this will work but conceptually it bothers me because an EmployeeViewModel is not an Employee (it contains an employee). If you're abstracting reality then, the blueprint of an Employee should not include properties or methods to be used by a View. To me Employee should be a POCO which could implement INotifyPropertyChanged and nothing more than that. You're separating View state from the Model itself. Having an Employee POCO makes it easier to UnitTest, create mock employees, map it to a database table through an ORM, etc.
As the name implies the ViewModel is the model for your View and the Model is the model for your business domain
Anyway that's how I see it. When I started doing MVVM work I had that same question but over the years seems like it makes sense.
In general, my Models end up being a Data Access Layer, be it through Entity Framework, a WCF proxy, or some other class.
Depending on concurrency issues, the class could be static or instanced. If you can separate the behavior enough, you could "split" the DAL classes into a separate model for each view model, but duplicate code could become a problem.
Wikipedia: MVVM
Model: as in the classic MVC pattern, the model refers to either (a) a domain model which represents the real state content (an object-oriented approach), or (b) the data access layer that represents that content (a data-centric approach).
Your ViewModel isn't a substitute for your domain Model. It acts as an intermidiate between your view and the model, including commands, binding collections to your view, validation, etc.
Your domain model should also be reusable across ViewModels. If you implement it all in the VM you will end up abusing the DRY principle by sharing specific VM logic across multiple VMs.
In my experience when you just use Domain models as the ViewModel (as a property of the VM) you end up with a lot of Keys that require you to either go get the text value and store somewhere else or you end up adding the property to the VM anyway. Your view typically has more info than just one single domain model (e.g. related objects, display values, text status values etc..), something that the Domain model has no need for and would ultimately weigh it down. The view model is dedicated to the needs of the view, it keeps coding the View simple and non-complex.
I came accross the following situation:
I have 2 view models and a single view which contains 2 user controls on which the view models will be bound to. The first VM is a Search functionality which returns a list of Persons, and the second VM is a more detailed description of each person.
I want to do the following:
public CompositeVM
{
public SearchVM SearchViewModel{get;set;}
public DescriptionVM DescriptionViewModel{get;set;}
}
As I have said, the search view model also incorporates a list of found persons, so I wish that when I select a person the DescriptionVM to be updated accordingly.
How can I achieve this type of communication between VMs? Should I set a SelectedPerson property on the SearchVM and pass it to the DescriptionVM when the selected list item changes (pretty high coupling to me)? Is there a more simple approach to this matter?
It's possible for CompositeVM to subscribe to SearchViewModel's PropertyChanged event and set DescriptionViewModel.SetSelectedPerson(SearchViewModel.SelectedPerson).
There is no coupling here between SearchVM and DescriptionVM, since they're not aware of each other. CompositeVM knows them both, and is also who's in charge of their interaction.
Alternatively you can use the Mediator-Observer pattern, such as the Messenger class in MVVM Light:
http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx
I'm trying to use CollectionViewSource to display some data, and all the examples/tutorials I've seen have a custom class built, which they use in another class, which inherits from ObservableCollection. I'm new to both using CollectionViewSource and this is only my third implementation of MVVM, so I might misunderstand the programming pattern, but my question is:
where do I put the ObservableCollection class and/or custom class?
I feel like they should go in the Model, but then I'm not sure what gets bound to the View. Do I just build these as external classes, and then reference them in Model/ViewModel?
Any help is appreciated
Firstly, I would say that there is no need to inherit from ObservableCollection<T> unless you are adding functionality to it which I have rarely, if ever, actually needed to do.
In most cases I create ViewModel properties of type ObservableCollection<T> and then populate them from the Model whenever I load the data. This has the advantage that the Model does not need to use ObservableCollection<T> (it can be any IEnumerable<T>) and it means that later when I (almost inevitably) want to wrap whatever I'm getting back from the Model in another instance-specific view model I am only obliged to change my existing view model classes.
Once you have a property on your view model you can simply bind your CollectionViewSource to that property and it will do everything from there. It's worth noting that the CollectionViewSource doesn't actually care about the type of the property, so you can expose your collection to the View as an ICollection<T>, IEnumerable<T> or (I believe) even as an object and the CollectionViewSource will still treat it the same as if it is exposed as an ObservableCollection<T>.
Sorry for the slightly rambling answer. The concise version would be "it depends on the situation" but I tend to follow this general approach in most cases.
I am investigating WPF's MVVM design pattern. But am unsure where to put the Data Acess code?
In some examples I have looked at, data access is performed directly in the ViewModel. It seems odd to put something like linq to sql in the ViewModel? Other examples have a seperate project for Data Access, this seems more like it?
Is this there a general approach? I feel like I am missing something here!
Thanks
Here's how I've been organizing my MVVM w/ LINQ projects:
Model - I think of the Model as the state of the system. It provides an interface to the data, and it keeps track of system status. The Model does not know about the ViewModel or View--it just provides a public interface to its data and various events to let the consumers (usually ViewModels) know when the state has changed.
ViewModel - The ViewModel is in charge of organizing or structuring all the data needed by the View, keeping track of the status of the view (such as the currently selected row of a data grid), and responding to actions on the view (such as button pushes). It knows what the view needs, but it doesn't actually know about the view.
View - The View is the actual look and feel of the UI. It contains all the built-in and custom controls, how they arranged, and how they are styled. It knows about the ViewModel, but only for the purpose of binding to its properties.
Gateway - This is the part that directly addresses your question. The Gateway (which is basically my way of saying "DataAccessLayer") is its own separate layer. It contains all the code (including LINQ queries) to CRUD or select, insert, update, and delete data from/to your data source (database, XML file, etc.). It also provides a public interface to the Model, allowing the Model to focus on maintaining system state without having to concern itself with the details (i.e., the queries) needed to update the data source.
DataAccess Classes - In C#, these are very simple classes that model your elemental data objects. When you select something using a LINQ query, you will usually create an IEnumerable<T> or List<T> where T is one of your data objects. An example of a data object would be:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
The big advantage of a design like this is that it really separates your concerns. Everything has a specialized job, and it's (usually) pretty easy to know what kind of thing goes where.
The disadvantage is that it may be overkill for small projects. You end up creating a lot of infrastructure for public interfaces that basically pass a single wish through several layers. So, you might end up with a scenario like this: [user clicks Submit, ViewModel tells Model to AddNewPerson, Model tells Gateway to InsertPerson] instead of a scenario like this [user clicks Submit, ViewModel adds new record to the database directly].
Hope that helps.
I would add another layer, essentially what you want is a data factory. You want to create a set of classes that will CRUD to the database for you and return clean POCO objects to the ViewModel.
A good example to look at would the Nerd Dinner book. It covers MVC not MVVM but the patterns are very similar and the way they access data in that solution would be good starting point.
Hope this helps.
Data access should not be in the view model, as this is supposed to be a view specific (possibly simplified) representation of the domain model.
Use a mapper of some sort to map your view model (the VM in MVVM) to your model (the first M). New objects in your model can be created using the factory pattern. Once created, you can store them in a database using the repository pattern. The repositories would then represent your data access layer. In your repository you could use an O/R mapper like NHibernate or Entity Framework.
EDIT:
I see that GraemeF suggests putting the data access code in the model. This is a NOT a good approach, as this would force you to update your domain model if you were to move from e.g. SQL Server to Oracle or XML files. The domain objects should not have to worry about how they are persisted. The repository pattern isolates the domain from its persistence.
MVVM stands for Model, View, and ViewModel. The piece you are missing is the Model, which is where your data access code lives.
The ViewModel takes the Model and presents it to the View for display, so typically you would have something like this:
class PersonModel : IPerson
{
// data access stuff goes in here
public string Name { get; set; }
}
class PersonViewModel
{
IPerson _person;
public PersonViewModel(IPerson person)
{
_person = person;
}
public Name
{
get { return _person.Name; }
set { _person.Name = value; }
}
}
The PersonView would then bind to the properties of the PersonViewModel rather than directly to the model itself. In many cases you might already have a data access layer that knows nothing about MVVM (and nor should it) but you can still build ViewModels to present it to the view.
Your ViewModel should be a thin layer that just services the view. My rule of thumb: if it has to do with the presentation of the UI, then it belongs in the ViewModel, otherwise it should be in the Model.
The WPF Application Framework (WAF) contains a sample application that shows how the Model-View-ViewModel (MVVM) pattern might be used in combination with the Entity Framework.