Im using MVVM.
I am implementing my data as OberservableCollections in Model, and I want the ViewModel to listen to and update any changes in the OberservableCollections of data in Model.
I know you have to implement some Actions, e.g. inset, add, etc in ViewModel. But I can not find any tutorial on it, can someone please provide some ideas, thanks :)
Since you are new to the MVVM pattern, read this post by Jeremy Likness, a Silverlight MVP. He gives basic examples of ViewModels, views, models, binding, commanding, etc.
As far as passing the model objects to the ViewModel, that all depends on where the model objects are coming from. For example, in most LOB applications, you will get data from the server via WCF, which introduces a layer of complexity to the pattern and the implementation.
If instead you mean "how does my ViewModel get notified when the user changes some data on the view", then that notification comes from your ViewModel implementing INotifyPropertyChanged, and your View binding to the properties exposed by your ViewModel. I think reading Jeremy's blog post will clear a lot of this up for you.
Related
I have a C# Application with two different views. Each view has an own ViewModel. The ViewModels access the same Model. The Views need the data from the same Model in a different format. The ViewModels handle the formatting and validation.
Both ViewModels should be able to communicate with each other in some way. For example if ViewModel1 updates something in the Model ViewModel2 should also update his View. The ViewModels don't have to know each other, they should just get synced when one side changes something.
I found some old posts aout the Mediator pattern. Is this still the way to go? I think the Observer pattern would not work here. The only alternative I could think of was to create a Interface on both ViewModels which let them talk to each other.
i think what your looking for is Message-passing system for your View Models.if you what them to be loosely coupled you can use events to implement one by yourself.
also there is Event Aggregator class in prism library that do the same.some classes subscribe and some publish their messages.
The pattern most relevant to this would be MVC. If you are using .Net Core, you can read up on it on the Microsoft Docs online.
The Controller would be able to return a View Model that has the updated values. You could also have just 1 View model that is used by both views that you have.
I'm quite confused about the architecture of my MVVM application (formerly WinRT, now targeting UWP) concerning data access. I'm quite unsure how to propagate changes across the UI and where to put access to the data layer.
Here's the basic architecture:
Model layer: contains models that only have auto properties (no navigation properties that reference other models, just Ids; so they are basically just representations of the database). They don't implement INotifyPropertyChanged.
Data acccess layer: A repository that uses sqlite-net to store models in a database. It exposes the basic CRUD operations. It returns and accepts model from the model layer.
ViewModels:
ViewModels for the Models: They wrap around the models and expose properties. Sometimes I two-way bind content of controls (e.g. TextBoxes) to properties. The setters then access the data layer to persist this change.
PageViewModels for Views: They contain ViewModels from above and Commands. Many Commands have become very long as they do the data access, perform domain specific logic and update the PageViewModels properties.
Views (Pages): They bind to the PageViewModels and through DataTemplate to the ViewModels for the models. Sometimes there is two-way databinding, sometimes I use Commands.
I now have several problems with this architecture:
Problem 1: One model can be represented on the screen at several palaces. For example, a master-detail view that displays a list of all available entities of a type. The user can select one of them and its content is displayed in the detail view. If the user now changes a property (e.g. the model's name) in the detail view, the change should be immediatelly reflected in the master list. What is the best way of doing this?
Have one ViewModel for the model? I don't think this makes much sense, as the master list needs only very little logic, and the detail view much more.
Let the model implement INotifyPropertyChanged and thus propagate the change to the ViewModels? The problem I have with this, is that the data layer currently doesn't guarantee that the objects it returns for two read operations on one model id are identical - they just contain the data read from the database and are newly created when they are read (I think that's the way sqlite-net works). I'm also not really sure how to avoid memory leaks happening because of all the PropertyChanged event subscriptions from the ViewModels. Should I implement IDisposable and let the PageViewModel call its children's Dispose() method?
I currently have a DataChanged event on my data access layer. It is called whenever a create, update or delete operation occurs. Each ViewModel that can be displayed simultaneously listens to this event, checks whether the changed model is the one its the ViewModel for and then updates its own properties. Again I have the problem of the memory leak and this becomes slow, as too many ViewModels have to check whether the change is really for them.
Another way?
Problem 2: I'm also not sure whether the place I access data is really well chosen. The PageViewModels have become extremely convoluted and basically do everything. And all ViewModels require knowledge of the data layer with my architecture.
I've been thinking of scrapping data access with sqlite-net and using Entity Framework 7 instead. Would this solve the problems above, i.e. does it guarantee object identity for one model when I use the same context? I also think it would simplify the ViewModels as I rarely need read operations, as this is done through navigation properties.
I've also been wondering whether having two way databinding is good idea at all in a MVVM application, as it requires the property setter to call the data access layer to persist the changes. Is it better to do only one-way binding and persist all changes through commands?
I'd be really happy if someone could comment on my architecture and suggest improvements or point to good articles on MVVM architecture that focus on my problems.
Have one ViewModel for the model? I don't think this makes much sense, as the master list needs only very little logic, and the detail view much more.
ViewModel is not dependent on the model. ViewModel uses the model to address the needs of the view. ViewModel is the single point of contact for the view so whatever the view needs the viewmodel has to provide. So it can be a single model/multiple models. But you can break down a single ViewModels into multiple sub ViewModels to make the logic easier. Its like detail pane can be separated into a user control with its own view model. Your master page will just have the window that will host this control and the MasterViewmodel will push the responsibilities to the sub ViewModel.
Let the model implement INotifyPropertyChanged and thus propagate the change to the ViewModels? The problem I have with this, is that
the data layer currently doesn't guarantee that the objects it returns
for two read operations on one model id are identical - they just
contain the data read from the database and are newly created when
they are read (I think that's the way sqlite-net works). I'm also not
really sure how to avoid memory leaks happening because of all the
PropertyChanged event subscriptions from the ViewModels. Should I
implement IDisposable and let the PageViewModel call its children's
Dispose() method?
The danger is not using INotifyPropertyChanged, but as your rightly said its with the subcribing and unsubscribing. Wherever there is a need to subscribe to any event - not only INotifyPropertyChanged you need to use IDisposable to unsubscribe itself and its child ViewModels. I am not clear on the datalayer you describe, but if it publishes the property changed event for any modification I dont see any problem using INotifyPropertyChanged.
3.I currently have a DataChanged event on my data access layer. It is called whenever a create, update or delete operation occurs. Each
ViewModel that can be displayed simultaneously listens to this event,
checks whether the changed model is the one its the ViewModel for and
then updates its own properties. Again I have the problem of the
memory leak and this becomes slow, as too many ViewModels have to
check whether the change is really for them.
As I said earlier, if you handle the subscribe/unsubscribe properly for all models you need not worry about performance issue of INotifyPropertyChanged. But what might be adding to the problem is the number of calls you make to the database for requesting data. Have you considered using Async...Await for the data access layer which will not block the UI for any update thats happening. Even if the data update is slow a reactive UI which doesnt get blocked by the data calls is a better option.
So try adding a data access service which is abstracted over the DAL layer and provide a asynchronous approach to accessing the data. Also have a look at the Mediator Pattern. That might prove helpful.
I'm also not sure whether the place I access data is really well
chosen. The PageViewModels have become extremely convoluted and
basically do everything. And all ViewModels require knowledge of the
data layer with my architecture.
2 main problems i see,
If you feel the PageViewModel is too huge break down into sub view models of manageable size. Its very subjective, so you have to try to see what all parts can be broken down to its own component/usercontrol with its own viewmodel.
When you say ViewModels require knowledge of data layer, I hope you mean they are dependent on a Interface that manages the DAL layer services and doesn't have direct access to class with CRUD methods. If not try to add an abstract layer which does you actually do in your view model. And that will handle the DAL CRUD operations.
I've been thinking of scrapping data access with sqlite-net and using
Entity Framework 7 instead.
Don't try to replace sqlite-net with EF without hard evidence. You need to measure performance in your app before trying to jump into such big changes. What if the problem lies in your code rather than the component you are using. First try to fix the above mentioned issues then you can segregate the DAL layer via interfaces and replace it if needed.
I've also been wondering whether having two way databinding is good
idea at all in a MVVM application, as it requires the property setter
to call the data access layer to persist the changes. Is it better to
do only one-way binding and persist all changes through commands?
If you are making a call to database directly everytime you make a change to the field/ for every key stroke then its a problem. Then you should have a Copy of the Data Model and persist the changes only when you click the save button.
I have viewmodel1 and viewmodel2.
Viewmodel1 needs to show data from a list of some sort contained in model.
Viewmodel2 needs to input data to the list contained in model.
So both Viewmodel1 and Viewmodel2 need to "know" about model.
What is the proper way to do this in MVVM?
Should I create model in app and give viewmodel1 and viewmodel2 a reference to it or?
I find it helps if I think of a ViewModel as being a Model, translated just for the View.
You have a few choices:
Create a controller which sets up the ViewModel. This is usually a good choice if the ViewModel needs information from more than one place. You can either give the ViewModel a reference to all the information it needs, or make it a Plain Old .NET Object (PONO) and have the controller set it up for you.
Just pass the reference to the ViewModel as you suggest. Useful if no interaction is required between different classes
Wire up the EventAggregator, which can be used to publish a notification when models change, and pass a Repository to the ViewModels so that each of them can go and get / store the model when they need to.
I really like the last pattern as it's easily scalable if you find you need more presenters or controllers with access to these kinds of models. It also lets you inject a repository, which means you can more easily move to a nice RESTful service-oriented architecture later.
If you haven't done much dependency injection before then please consider doing it through the constructor. This will help you avoid situations where things are trying to use your ViewModels before they're ready, and lets the ViewModels do their own work. You might also want to look at frameworks like Unity or Castle Windsor which can help you do this kind of wiring, but that's really only for big Enterprise projects (and not even all of them).
That's perfectly fine. Models are meant to be just what they sound like: data models. They're meant to be dummy objects that hold data, which the rest of the application can use as needed.
ViewModels are models that reflect the View. For example, suppose you had a LoginViewModel and an ManageUsersViewModel. Both ViewModels would work with the UserModel data object, however they are entirely different ViewModels for entirely different things.
In most cases, I would leave the responsibility of loading Models up to the ViewModel. For example, you normally wouldn't pre-load the Users list prior to the User logging in so you'd have their User object available. Insetad, your LoginViewModel would make it's own database call to get the User model of the user logging in, while the ManagerUsersViewModel would make its own database call to get the list of users that can be modified.
You must be thinking in a wrong way.. in MVVM your model are contained in ViewModels all the way to the views.. lets say if there is a ObservableCollection then there will be a property in you viewmodel for this and you should be initializing this collection in constructor/some method of the ViewModel.. both viewmodels will initialize ProductTypes like this.. In my opinion you should try create Classed For Model,ViewModel,Repository and use IoC in it..
here is a really good video on mvvm you should try this video and have a look at the code as well.
http://blog.lab49.com/archives/2650
If the List you mentioned is something that will never change you should try creating a singleton ViewModel for this and reference that viewmodel in other viewmodels.
Regards.
In MVVM pattern I don't want to think about the view while creating the model. So I use public properties with data stored in ILists and so on.
But then my viewmodel isn't informed of changes done to these lists on model side.
Should I use ObservableCollections in my model instead? But this seems strange to me.
Yes, you should use ObservableCollections. I don't know what would be strange about this? All an ObservableCollection does is notify any listeners of changes. That doesn't necessarily have to be a UI.
Your ViewModel shouldn't know anything about the actual View using it, but as it's a ViewModel, it is ok for it to assume something is going to use it, so ObservableCollection is the way to go and also, as far as i know, common practice.
Also, the listeners know exactly which items have been added or removed, so there's no need to update the entire list when changes occur => better performance for updates. That's also what Microsoft says (can't find the article about that right now though)
this is also the reason why you see most people implement INotifyPropertyChanged on their data model, because you want the viewmodel to be notified everytime the data model changes.
I'm trying to understand the basic MVVM design approach, but I dont' understand where is the best tips for work with CRUD operations.
a. Create a ViewModel with abstract of properties and in this ViewModel implement CRUD methods?
b. Create ViewModels base and then add properties for ObservableCollections of Viewmodel?.
Can you said me , how you i can do this, please!.
With MVVM, all business logic and interaction with a data source should occur in the model.
Your ViewModel will expose the data and functionality that the View requires.
So if for example you had a button on your view that removed an item from the database, the button would bind to an ICommand instance on the ViewModel. Once the ICommand executes, the implementation of this command will communicate with the model to make sure the item is deleted. The viewmodel is then populated with the new data to allow the view to update.
I have found this gem here:
https://www.youtube.com/watch?v=mtdiDXhqhso&list=PL0wefbX90CmYNrO67FtZNDlnSrmWkF4bJ&index=1
This is WPF with MVVM.
What you'll learn here:
CRUDS in a List/Observable collection
CRUDS using ADO.NET
CRUDS using Entity framework
I know that this post already has an accepted answer, but for future dev's, learning MVVM will not be easy (looking for resources that is straight to the point). That's why I posted this to share to everyone good knowledge.