MVVM with continuously updated data - c#

I am currently working on a Windows Store application (8.1) which is supposed to do the following:
Talk to a USB HID Device (figured that out)
Display data from that device (I want to use Oxyplot for displaying this data, got that)
Use MVVM (I selected SimpleMVVM toolkit since it already has templates for VS2013)
Create a mock data provider which generates random data and feeds it to my ViewModel
Now I am kinda stuck here regarding where to put the data. I use a Queue to store my values (I always want the last 100 values displayed). Now, what do I put into the model and what do I put into the ViewModel.
E.g. would I put the Queue containing the data points into my ViewModel? How would I trigger the process "Get some data every 1 second" correctly. I thought of using a System.Threading.Threads.Timer for that. Where would I put that? Into the MockDataServiceAgent? In that case: How do I access my ViewModel from the ServiceAgent to execute the update?
Everything is fine if you have buttons and stuff, but what if you have random events which are effectively triggered by "something else" than the view?

Your Model is your domain object, it represents the actual data or information you are dealing with. An example of a Model might be that of a Car containing a make, model, colour etc. The main thing here is that the Model maintains information and not behaviour.
The ViewModel is your presentation separation layer, it can wrap one or more of your Model objects. It is the glue between your View and Model exposing commands and methods which maintain View state and can alter the state of your Model as a result of actions on the View.
Your data should be maintained by your Model, or Models. It would be your ViewModel which would expose that data and provide a mechanism for your View to consume it. An ObservableCollection is a common mechanism for exposing a collection of data to a View as it is dynamic and provides notifications when it has items added, removed or is refreshed entirely.
Ideally you do not want your objects to have strong links to one another, so to communicate between objects you might want to consider some implementation of the Mediator design pattern. Most MVVM frameworks have some implementation of this either as a Mediator or EventAggregator message bus. These provide a publish and subscribe mechanism where one object publishes a notification containing some data and one or more subscribed objects will receive that notification and process the data accordingly. None of the objects involved know who is a publisher, subscriber or who is involved, they only know of the Mediator implementation.

You could put your queue containing the data in your ViewModel, as an ObservableCollection, then when the ObservableCollection is changed it can update whatever it is bound to. It would be best to keep the link between the ServiceAgent and ViewModel loosely coupled, I would suggest using SimpleMvvm's messaging system, if it has one, I know MvvmLight (another Mvvm toolkit) has one. Or you could build one yourself by using the Mediator pattern. Or if you don't want to use a Mediator, use an IoC Container. Just get your data service process to update the ObservableCollection, and that should cancel the need to worry about events (for updating the UI).

Related

Domain, DTO and MVVM models (WPF) - where to put INotifyPropertyChanged?

I need to create WPF app with MVVM pattern as a layer of my solution.
Solution have: Domain, DAL (returns Domain objects), DTO, BLL (returns DTO objects).
The problem is that to implement MVVM pattern it seems to me that i have to duplicate my Domain models in WPF project so I can implement INotifyPropertyChanged interface on them? Then I also have to map these models to DTO so i could use BLL services?
Inotifypropertychanged needs to be implemented on anything you bind AND you want to notify when a property changes.
You don't always need that notification.
For example.
You're editing a record, you make changes.
Maybe that's all you're doing with that data and the only bound field is that one you just typed into.
Which means you could, potentially, just bind a dto property with a plain get and set.
Although - this should be presented from a viewmodel which implements inpc because there's a very subtle memory leak waiting to catch you out otherwise.
Back to our imaginary app though.
Why might we not want to bind straight to an entity framework or dto object?
How about when you try and save thosee changes. Validation fails.
But you changed that object - those new values are naughty values.
The user is "forced" to fix them or you somehow back out your changes.
How do you back em out?
Are you editing some dto?
Because your user just broke that data.
If you have some collection of data cached somewhere, are you changing one of those directly?
Obviously, you could go re-read that data out the database again.
There again if you don't let them edit that dto then you don't need to do that.
I would usually copy data from a dto into a viewmodel and work in that.
I use a reflection based property copying routine that identified common properties between two types.
I validate that viewmodel as each property transfers to the vm and all of the object on commmit.
It's values are copied into a dto and sent back to the repository or UoW update method.
ViewModels are designed to work with Views, so they don't always map 1-1 with domain objects.
Sometimes a view needs to display data from multiple domain objects.
Sometimes a view only needs some of the data from a domain object.
Sometimes a view needs data that's only relevant to the view (selected item for example).
So, the question of how to populate data into the ViewModel can be complex. Most of the time I just skip the DTO and have the ViewModel get the data itself. Or if that's not possible have the DAL try to populate the ViewModel as if it was the DTO. It really depends on how the rest of the apps infrastructure works. In general I try to have as little number of layers as possible. Ideally I have my ViewModel getting the data it needs as directly as possible.

MVVM architecture: one model - several view models + place for data access

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.

MVVM, ObservableCollection, async, etc

So, I'm on to the next phase of my education and have reached a bit of a blocker related to my use of SQLite (this is for a universal app, with my current focus being on the Windows Phone side of that solution). My question is somewhat independent of SQLite but I will use it as an example.
I am looking at SQLite as the database for my app (based on various suggestions and comments here and elsewhere). Specifically, I am designing my view -> viewmodel -> model and I'm not sure of an appropriate pattern for passing around ObservableCollection.
Let me start at the model. I am making a call to SQLite-net's QueryAsync() method. So, buried deep in the model I have any await on the call to QueryAsync(). The method in which that lives (let's call it GetData(), for simplicity) is marked with async. So, that's the model.
Up at the view level I need to bind to a property of the viewmodel. Let's call that property GetDataVM(). Since it's a property I use a getter - and, as far as I can tell, I can't use await in getters. Is that true? Given the asynchronous call in the model - QueryAsync() - it seems I need an await, right?
I am sure I have some basic assumptions wrong here. But the basic principle I am trying to understand is what a control in my view must bind to when that property calls a method in the model that includes an async method.
I'm not finding this particularly easy to explain :) But, stepping right back, what I want is very simple, conceptually. I want a control to bind to a viewmodel property that, in turn, retrieves data from the model, which retrieves data from SQLite.
And I'm confused :)
Any help would be most appreciated (probably starting with clarifying questions about what the heck I'm trying to achieve :)).
Thanks.
I have an MSDN article on this topic.
The gist of it is this: as others have noted, a property read should be an immediate operation, whereas an asynchronous operation is (generally speaking) not immediate.
So, what you first need to do is decide what your UI will look like while the data is loading. When your VM loads, it should initialize its data in that "loading" state, and when the data arrives, the VM should update to the "ready" state (or to an "error" state if the operation failed).
In my MSDN article, I introduce a NotifyTaskCompletion<T> type that is pretty much just a data-binding-friendly wrapper around Task<T>. This allows you to do the state transitions via XAML bindings.
You are right, getters are not async. I would also refrain from trying a hack to make them work that way.
It is considered bad practise to have long running getters and good practise to wrap long running processes as await able asyncs.
You can see why the two are not compatible.
Instead, is it possible to trigger your async call from a command? That way you can make the call async and just assign the result to the property via the setter, that should call INotifyPropertyChanged PropertyChanged event to update your UI.
In general it is the ViewModel's responsibility to load the model (of course it could pass this responsibility to a repository class)
This way the ViewModel can contain the awaits and the Model can consist of plain data containing classes.
The View and ViewModel decide when to sync the model to and from the data source.
The role of the ViewModel is to mediate between the Model and the View. Most of the times I do not design the Model but accept it as a given from the data source and in many cases the Model is generated from a contract by a tool (Entity Framework, Web Services, ...) So I treat the Model as a dumb data container that changes when the data source changes.
The design of the View is driven by the user (requirements) so I am not in control of that either.
The ViewModel is where I get to design and code the transition between View and Model so that is also where I decide (based on user and technical requirements) when and how to load the data (Model) and transform it to match the structure needed by the View.
Many times the actual connecting to the data source is coded in a repository class so the ViewModel is not aware of the actual data source (connection/technology) This way it is easier to connect to another data source to support unit testing or the actual migration to another data source.
Try to put one responsibility in each class/layer.

Multiple viewmodels using 1 model?

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.

How do I handle events from controls inside a User Control derived from a Tab Page meant to be added dynamically to a Tab Control at run time?

I created a User Control derived of a Tab Page with certain controls such as ListView, Buttons, and Textboxes in it, to add Tab Pages to a Tab Control dynamically during run time.
How do I handle the events from such controls within each User Page (multiple instances of these user control tabs) in my main form where my Tab Control is going to be located? Initially I want to be able to communicate the data in some of these controls inside each User Page back to the main form.
This isn't just in regards to tab pages, although we use a tab page derived in a similar fashion. Sending events willy-nilly through the UI causes me much confusion (keeping the order in which the various events trigger and so on). Instead, I create a controller class which is passed to the various UI components and those components notify the controller with changes and the UI elements subscribe to events on the controller to receive information about the environment.
To make this concrete, each of the derived Tab Pages is passed a reference to the controller. They may change the state of the controller based on user actions. Say the current record is changed, the UI calls a method on the controller telling it the new record.
The other UI elements on the page are notified of this change because they subscribe to the controller's OnCurrentRecordChange event.
While this introduces another class into the mix, the advantage is that you have a single controller orchestrating the changes to the UI, rather than a bunch of events percolating and passing information around. I find that is also breaks dependencies on UI elements collaborating: I can add, remove or change UI elements and as long as they all speak to the controller for updates there is far less code rework.
If you have ever found yourself debugging UI "loops" (where changes in one control are triggering changes in other controls which trigger yet more changes which eventually affect the original component) then the extra work of a controller class will pay off immediately.
Update: Answering your comment... A first stop would be to read up on the Model View Controller architecture: http://en.wikipedia.org/wiki/Model%E2%80%93View%E2%80%93Controller
For a concrete example: http://www.dotnetheaven.com/Uploadfile/rmcochran/MVC_intro02012006001723AM/MVC_intro.aspx
When working with Windows Forms many people get stuck in a two tier design: UI + Data Layer. The binding system makes this very natural as there is an easy way to get at data (Entity Framework, LINQ) and an easy way to wire data to the UI (the designers). Adding a controller between them isn't as hard as it may seem though.
In my work I use LLBLGen (http://www.llblgen.com/defaultgeneric.aspx) for my low level data layer, but you could substitute LINQ or Entity Framework or any other data access tool and the general overview would be the same.
Above this layer I build my business objects. Many of them are nothing more than facades for the LLBLGen objects (if my business rules don't say much about the entity), while others have a lot of validation built in and they aggregate several low level objects into more usable business objects. Finally there are the business objects that don't directly have entities behind them (communications objects between systems, for example).
The controller object I mention lives alongside my business objects in that it knows about these objects and it even hands them out to the UI for data binding purposes. When the UI wants a change make, it notifies the controller and it uses the business objects to ensure the updates are permitted and if so passes the changes back down the the data layer.
In the diagram on Wikipedia, the View is my UI. The Controller is my coordination object which is mediating changes in both directions while the Model is my business object layer (which has a low level below this, but that is an implementation detail that is hidden from the higher layers).
Although going from "View <-> Model" (classic data binding) to "View <-> Controller <-> Model" seems to be adding complexity, the major benefit is that the controller becomes the one stop shopping location for "truth" about the application. The UI requests data from the controller, so the controller knows about all the UI elements that have a given data binding. If things change, an event notifies all the UI elements and they change visually for the user. The nice thing is that there is one "truth" about system state, and that is the truth the controller is managing for the UI.
When data needs to be persisted, the request goes to the controller to update the model. Again, we have a single place for the coordination of the save and subsequent updates. All of the data validation integrity rules are in the business logic layer (the Model) so the controller's code is kept light.
By separating your UI concerns, your coordination concerns and your business logic concerns
you end up with each having very "lightweight" methods and properties. More importantly, each subsystem can take a very simplistic view of the application as they focus on that piece of the puzzle instead of threading events, UI updates and data updates in one monolithic piece of code.
For further reading I would recommend any of the articles or books about ASP.NET MVC. While this is not Winforms, the basic ideas underlying the MVC can be applied to winforms. There are some good comments here as well: https://stackoverflow.com/questions/2406/looking-for-a-mvc-sample-for-winforms
I should be clear that what I am doing with my projects is probably not considered "pure" MVC, but simply a separation of concerns along the natural fault-lines found in the applications we develop. We don't use a "framework" for this (although some code generation is involved).

Categories

Resources