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.
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.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm in the design phase of a WPF application with complex requirements:
I have to control the view by code because I have to enable, disable or hide elements depending on the user permission. Additionally in a TreeView I have to control the ContextMenu of the TreeViewItems depending of the Item-Type (internal logic) and the dependency of the user permission.
The Data to display are loade by stored procedures to datasets (multiple tables).
What's the experience with MVVM and maintenance (code complexity of MVVM compared with direct code behind) and all the stearing of controls visibility.
Automatic testing is not needed because the visible part must be included in the testing all the time (visibility of controls depending on loaded data)
Any sugestions are welcome
Being at the design phase makes this much easier to suggest patterns and practices, your question isn't very clear, so I'll address each point you have made.
I have to control the view by code because I have to enable, disable or hide elements depending on the user permission. Additionally in a TreeView I have to control the ContextMenu of the TreeViewItems depending of the Item-Type (internal logic) and the dependency of the user permission.
This sounds pretty straightforward, using the MVVM design pattern in this scenario would most probably require an IValueConverter to convert a view model Boolean property to a view-friendly Visibility value. This explains how you can achieve that.
The Data to display are loade by stored procedures to datasets (multiple tables).
I would suggest looking into the Repository Pattern. This, coupled with the MVVM design pattern should suit your requirements nicely.
What's the experience with MVVM and maintenance (code complexity of MVVM compared with direct code behind) and all the stearing of controls visibility.
The purpose of MVVM isn't to have no code-behind, it's to ensure that code belongs in the right place. Code-behind is not a bad thing, it's view related code. There is a much more detailed answer here.
In your scenario, it's more than likely that you need properties in your view model to indicate whether the user has the authorization to view certain controls, I assume these permissions are held in the database, therefore the properties would need to live in the view model as you can't get to the database from the view. I hope that made some sense.
MVVM is more maintainable than a code-behind solution as your view models are decoupled from the view, therefore if the view changes, the view model does not necessarily need to change too. This is also true for repositories and models.
MVVM paves the way for a more agile solution.
I came from a winforms world, and implementing any MVX style pattern seemed like more hassle but after working on WPF, I can say that MVVM is the best way to proceed. The whole mechanism is supported out-of-the-box.
First, the key benefit is that it enables true separation between the 'View' and 'Model'. This meane that if/when your model needs to change, it can without the view needing to and vice-versa.
Second, your 'model' might have all the data required by your 'view' but this data might be required by your 'view' in some other way. For these transformations 'view model' is required, whithout which these changes would be needed with duplication in model.
You can also use a 'viewmodel' to aggregate parts of your model that exist in separate classes/libraries to facilitate a more fluent interface for the 'view' to deal with. It's very unlikely that you'll want to work with data in your code in the same way that a user will want to or will want that data presented to them.
On top of that, you get support for automatic two-way databinding between the 'view' and 'viewmodel'.
I would also recommend the video here:
http://blog.lab49.com/archives/2650
The scenario you are describing is nearly a "perfect-fit" for using MVVM. You can control the visibillity depending on the permissions just by using bindings in the view. You will not need to write any code-behind in the view (beside you have to do some specific UI things) because the entire connection between your "data" (models) and the displaying (view) is done in the viewmodel.
That also enhances the maintainability, you can touch the view without changing the viewmodel and vice versa.
At the beginning it will be a bit overwhelming and you have to create many properties which seems a bit messy.
In a nutshell:
View: just the form (layout) the user will see (displaying the data)
ViewModel: the logic which (in a way) "controls" your view and connects it with your data (models)
Model: your business logic
For example: In the viewmodel you can set the state of a property which indicates if a control element is visible for the user or not and this property is then bound to the view. In the view you do nothing beside binding the property in the XAML code. It's a good way to stay clean.
I hope this was a bit helpful.
EDIT: here is a quickstart and here are some further information
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 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.