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.
Related
In learning Xamarin.Forms/UWP/WPF tutorials always tout MVVM as the design pattern of choice and I've followed suite, but I've never understood why. To contrast, in asp.net MVC the templated framework is used to great effect, Controllers deliver models to the view (HTML of some sort).
But in the Xamarin.Forms/UWP/WPF and others, we create a completely new class, ignore the code-behind file that cannot be removed and relegate it to telling our view where to look when binding data.
The only reason I could think of that makes MVVM better is if we could supply logic where different VM's could be 'injected' into the same view, maybe that would justify it.Though I have no idea how to do that.
Otherwise, how is creating a view model class better than using the code behind file? Is it really worse separation of concerns just because the view and code behind have the same name and are instantiated together?
MVVM pattern is much cleaner than using code-behind.
Separation of concerns
Imagine you have a view and a code-behind implemented. Now the business comes with a request to completely change the way the controls are presented - replacing them with new controls, changing layout and so on. Chances are, you will be forced to rewrite a lot of code just to satisfy the requirement, because the code-behind is directly tied to the view.
Now in case you have MVVM in place, you can easily swap the View part of the equation for any view which utilizes data binding to the right properties in a View model. You could easily present a single View model in several different ways - like creating multiple different views for different user roles while the view model stays exactly the same, you just choose what to display and how.
What view model actually creates is a middle layer between data and their presentation and makes it possible to more easily transform the data the view uses and change the presentation without affecting the view model if the interface is kept intact.
Data binding
Also if you are meaning purely code-behind without data-binding, the advantages of MVVM become even clearer. When you have a data-bound property that updates after user input in a TwoWay manner, for example if you have a form the user has to fill out, you don't have to remember to fetch the latest "changes" from the control using Text property, you know the latest version is already there in the data-bound property. In addition, you can add validation in the property setter, you can update other properties in the setter as well to orchestrate data handling in a much more abstract way than with code-behind approach, where you are tied to events and having to remember where the data come from and which specific controls and which specific properties you have to update. Imagine you display a given text in multiple places - with data binding you just set a single property and rely on {Binding} to display the text in all bound controls. With code-behind only, you need to remember which concrete controls display the text and when you add a new control, you have to update the code-behind appropriately, which is far less convenient.
Cross platform development
Another example would be having to develop a cross-platform application with native UI using MvvmCross. Here you can decide that some views or some functionality will not be available for certain OS or that you want to just implement it later. This is entirely possible - you just don't provide the UI for that functionality and the view model can stay the same.
View state
Finally - having all view state in code-behind means that when you navigate away, you must store the state somehow and restore it when navigating back because a new page is created. With MVVM you may decide to keep the view models of the navigation stack in memory and when navigating back just set the DataContext of the page to the existing view model instance to get back just in the same state as you left off.
Overall I see MVVM as a great pattern to improve flexibility of your codebase and it makes your solution more future-proof and resilient to changes.
this could be a long question, I'll do my best to ask it properly.
I want to read large .txt files with lots of numerical data. In each file there will be "channels" (30-50 channels, with own name, axis units, and of course, data). So I've created a class Channel with that properties, and a class File that has a list of that channels. It also has a method that reads the file and stores everything in lists.
I want to be able to load several files at the same time, and for that I've created a UserControl that consists in a button for loading the file and a ComboBox that displays each channel:
(The ComboBox is bound to an ObservableCollection)
The data is stored in the code behind of the user control. So when I insert in my MainWindow several UserControls I can't access that data.
What I want is have several UserControl...
...and be able to plot the data from each one in that Plotter, and be capable of some control (previous, next..)
My first approach was to store everything in the UserControl, that was easy to do but ineffective.
So what I figured out that might be the solution is to store everything in other place and then access to there from the MainWindow or other place. I've tried VERY HARD to learn MVVM and use it in my project. But I must be very STUPID because I can't get it.
My new approach is described in the next scheme:
My questions:
1.Is this the correct way of doing it? If the MVVM is the way, please, I beg you, please, guide me just a little bit in the beginning, because I am not capable to translate that intricate examples out there of MVVM to my project.
2.If I'm doing it more or less right, how could I store all that data in some other place and the access it from MainWindow? (in my File class I have a method that stores all in lists, so in my UserControl I have the "Browse" button that gets a filename, and then with the read() method I store everything inside (?) the File class, or at least inside the place I've created the new File: the UserControl).
I'll post code, pics, more info, anything if needed. Thanks.
If the MVVM is the way, please, I beg you, please, guide me just a little bit in the beginning, because I am not capable to translate that intricate examples out there of MVVM to my project.
You're already half-way to using something that's MVVM, at least in nature. It isn't "the way", but it would definitely be a (reasonably nice) way to handle this.
In order to design this with an MVVM type of design, you'd want to make your "MY DATA" class be the DataContext of the UserControl. All of the data would be stored there (preferrably in ObservableCollection<T> instead of List<T>, as that will handle binding more effectively).
Your "UserControl1" portion would likely be some form of ItemsControl, bound to a collection of sources. The selected item could then be bound to something on your "MY DATA" class, which determined which "plot" should be displayed.
To answer your questions directly:
1.Is this the correct way of doing it?
This is definitely a step in the right directly. Storing your data separate from your controls is one of the key pillars to making your application more flexible and maintainable (and a large goal of MVVM).
2.If I'm doing it more or less right, how could I store all that data in some other place and the access it from MainWindow?
You handle this by setting the class as the DataContext of your UserControl and/or MainWindow. This allows you to bind to properties on your data class (which is effectively your ViewModel in MVVM terminology).
Also, I know you've tried to study and learn MVVM - and it's difficult to grasp initially, but it is worth the effort. I will say that your design scenario (which is effectively a list of "options" on the left, and a "detail" pane on the right) is not an uncommon one - it's actually similar to my example in my blog series on MVVM, and should be fairly easy to create once you understand the basics.
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.
The project I'm working on is quite large and we have a framework we developed for building simple UI screens easily. The two fundamental types we have are Search (search parameters + grid of results) and Detail (a set of editors that are usually populated from some model object).
The application is all C# .NET Winforms.
In the Detail we have the following process.
Load - Populate the edit controls based on the appropriate model object. Invoked just prior to the Detail being shown
User clicks ok
Validate - Validates the detail to ensure everything is consistent
Accept - Copy the updated control values back into the model
This all works nicely for simple stuff but in more complex cases I've noticed perhaps the above approach is not the smoothest.
The more complex cases mentioned above are when a Detail represents a model object and there is a grid embedded in the Detail which holds 'child' objects which can be added and removed. Typically you want to launch the child Detail and pass in the parent model object, however it is not fully populated/up to date at this point because that only happens when OK is clicked. I find myself working round this in an annoying fashion sometimes which leads me to the following question.
At a high-level, is the accepted/best practice approach for Detail screens like I describe to copy values to the model object when the control is changed, rather than waiting until OK is clicked?
If so, in a Winforms app, what is the best way to achieve this? I found some articles mentioning Control.DataBindings but it's not ideal because of the lack of compile-time safety on the binding. I've read WPF has good binding support, but unfortunately, I'm not using WPF.
For Winforms I would suggest that you look into the Model-View-Presenter pattern.
http://msdn.microsoft.com/en-us/magazine/cc188690.aspx
This might help:
Walkthrough: Creating a Master/Detail Form Using Two Windows Forms DataGridView Controls
http://msdn.microsoft.com/en-us/library/y8c0cxey.aspx
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.