I am creating a Windows Forms application that reads various tables from a database into a DataSet in order to display said tables in multiple DataGridViews. Rather than putting all my code in the code-behind file, I have started doing some research on different design patterns, and have found many articles/threads with the consensus that MVP is the best option for WinForms.
After doing a few tutorials, and starting to organize my code using the MVP pattern; I have placed my DataSet in what would be the Model, most of the logic in the Presenter, and everything else in the View.
My question is: where should I place the validation of user input? I do not want the user to be able to enter invalid values into the DataGridViews, and if they happen to do so, I would like to let them know the row/cell that has the error. Previously, I would handle the RowValidating event and check the row and cells of the DataGridView for any errors, and then display a message accordingly, but this seems to not fit within the MVP pattern.
Should I leave the validation in the view, or should it be moved elsewhere?
IMHO you should keep the view (the form) as simple as possible. You can indeed subscribe for the RowValidating event and call the presenter (presenter.ValidateRow(...)) from there and pass to it the info and let it handle the validation. The presenter on his turn can ask the model for some info if the validation logic happens to be complex and has to go all the way down (to the DB for example). It is the presenter's responsibility for how to handle the errors. When the validation process completes it's the presenter's job to call a method or set a property on the view in order to display failure or success. Remember that your view is just a "window" to the state of your business logic (objects). Ask yourself the question "Is my program going to work if I swap this specific view with another implementing the same interface but not written by me?".
You may want to take a look at this http://msdn.microsoft.com/en-us/magazine/ee336019.aspx article for further clarification on MVP pattern.
Related
I'm designing a C# / WPF application, and trying to adhere to MVVM (but I don't mind taking shortcuts, as I'm quite a beginner).
I have a ViewModel and several Models. In the View there is a TextBox that is meant to log messages about what is happening in the models. The text of the TextBox is already bound to a string property in my ViewModel, but how can I give my Models the ability to append text to that TextBox without breaking the MVVM concept too much?
I was thinking about using Trace and a Trace listener for my TextBox. Is there any other (simple) way?
Thanks
If you put functionality like networking in your model, it's not a model anymore. It will have to many responsibilities and will violate the Single Responsibility Principle (SRP).
Reduce your models to contain only logic tied with the model class itself. Move functionality like networking into service classes.
Update is result of user action in the same ViewModel
Call service classes from ViewModel (i.e. in commands representing user actions) and if the call is successful, get the updated value.
Update action happens in another ViewModel or somewhere else (timer/polling)
If the sync happens somewhere else, use EventAggregator. Your service can fire an event/message, your ViewModel will subscribe to it. When receiving this event, update your ViewModel and rise PropertyChanged.
I'm trying to learn MVVM and WPF and I'm using the MVVM Light Toolkit. Here's what I'm not fully understanding and maybe it's due to an incorrect architecture of my UI.
What I'm trying to accomplish is pretty simple actually. This is a utility application by the way. I want a window that serves as the 'controller' so-to-say that has a set of buttons. Each button should change the content of a frame. Example: one button loads a 'screen' ( or a 'view' if you will ) that allows the user to configure an 'Agency' which is a custom object. Another button loads a list of Users from the Agency that was in the first 'screen'. This 'Users' view needs to also be loaded in the same frame. In fact, as of right now, the window with all the buttons really is only responsible for loading the 'screens' in the frame. The meat of the application will be within all the separate 'screens'
What I am not understanding is 1) how to let each screen/view know about each other since one is dependent upon the other. It seems that in MVVM the ViewModel shouldn't know about anything. But in my case, I need to pass information around ( such as my Agency ).
If I can get some hints on what I need to look into, that would be great.
Thanks!
Some ideas that might connect some of the dots:
You'll most likely have one viewmodel per view ("screen").
Each viewmodel will contain all of the logic for its corresponding view
Viewmodels can and will know about the models (Agency, Users)
Viewmodels can communicate with each other via the Messenger in MVVM Light
Think of MVVM Light's Messenger as an "application-wide eventing system". When you send a message out from one view model, any other view model can be listening for that message/event and react to it as needed.
Does that help at all? Keep your thoughts coming and I'll keep commenting and I'm sure the community will as well :)
Few things:
each of your screens, should be separate view (eg. user control or new window - I suppose you've done that already)
every part of model (eg. Agency, User) you want to display in your application, should be wrapped with its dedicated view model
your views don't really need to know about each other; you can use commands or events on view models to get rid of those dependencies
view model only needs to know about one thing: model it's building on
it's good to think about view as really simple class, with one single responsibility of rendering content; no logic, no code behind (unless it's purely UI/display related) is something to follow
You can try to prepare your models first (if you haven't done that already), then make view models for them (thinking what properties of models you want to expose to views) and once that's ready, build your views basing on view models. Other way around is also viable option - pick whichever feels more natural to you.
One more thing: since you mentioned you can display several screens in one (I assume) main area, think about equipping your view models with something along the lines of bool IsCurrentlyActive property. This way, you can easily show/hide views with button clicks and still utilize binding mechanism.
They shouldn't know about each other. That is what the Messenger is for controllers and views subscribe to the events they are interested in. That way they don't need to know or care where they event originated.
Hmm Kendrick is faster. What he said.
Also it sounds like you kind of want an Outlook type interface, some navigation that loads other views. I had the same question a while ago. How to do Regions in WPF without Prism?
To better understand the MVVM pattern look at this article: WPF Apps With The Model-View-ViewModel Design Pattern
Also I advice you to look at Caliburn Micro framework.
I am creating a program which utilizes MVP architecture. Please tell me which is the best place to write the validation. Someone told me that the code in presenter should only contains logic to handle events raised from the GUI and format values collected from the model so that view can display values without any overhear. Is this correct?
I'm developing a WPF GUI framework and have had bad experiences with two way binding and lots of un-needed events being fire(mainly in Flex) so I have gone down the route of having bindings (string that represent object paths) in my controls. When a view is requested to be displayed the controller loads the view, and gets the needed entities (using the bindings) from the DB and populates the controls with the correct values. This has a number of advantages i.e. lazy loading, default undo behaviour etc. When the data in the view needs to be saved the view is passed back to the controller again which basically does the reserve i.e. re-populates the entities from the view if values have changed.
However, I have run into problems when I try and validate the components. Each entity has attributes on its properties that define validation rules which the controller can access easily and validate the data from the view against it. The actual validation of data is fine. The problem comes when I want the GUI control to display error validation information. It I try changing the style I get errors saying styles cannot be changed once in use. Is the a way in c# to fire off the normal WPF validation mechanism and just proved it with the validaiton errors the controller has found?
Thanks in advance
Jon
Two things:
1) Trust the data binding in WPF. WPF's data binding is incredibly robust and very useful - there's no reason to let your "bad experiences" with other frameworks deter you from using the DataBinding. It will dramatically simplify your code.
2) The best option for data validation is to use WPF's built-in data validation capabilities. If you make your Data Context implementation (where the data is held for binding) implement IDataErrorInfo, you'll get the appropriate validation styles nearly for free (and completely customizable). This is the proper way to handle data validation on the UI in WPF.
I am looking for a best-practise approach on how to do UI validation in a model-view-presenter architecture.
I need to validate some forms with a lot of controls. And to make it easy for the user, I store all errors or warnings with a reference to the control in a Log which is displayed to the user afterwards so that he can jump right away to the control he has to fix. This is done in the view-part, which is actually wrong since validation should take place in the presenter in order to exchange the view.
The problem for me of doing this validation in the presenter is that it is not just checking if provided values are wrong, it also needs to check if radiobuttons have been checked which enables a textbox, which then has to contain some text for example.
I was thinking of using the BindingSource in the presenter since it's reflecting the UI changes and is visible to the presenter. But I am not sure if this is the right way to go (and I think it's kind of ugly)?
By the way: the validation takes not just place before I write to the database; it already takes place while the user is working on the forms.
Could anyone think of a good way of doing this?
We finally found a solution.
It will be done as I expected, using the DataSet in the presenter which is processed by different validator classes (one for each of our "pages"). The most difficult part is, when controls depend on each other (but in the end its just checking if values are set in the DataSet). Currently it is not possible to jump to the control to fix errors but this will be added later via Reflection by passing the name of the control to the LogEntries and the view can then figure out where this control is.