I have been using winforms for many years. Normally I write a form and that form, in the code behind does everything (validates user input, communicates with the database…). Recently a friend introduced me to MVP and I have been trying to learn to use it. The problem I am having is replicated some of the stuff I used to be able to do with the form. For example, in the past if I had a textbox and the user entered something invalid in the textbox, I could turn that textbox red, set focus on the textbox and alert the user that they entered something invalid in that testbox. With my validation now being done in the presenter or model layer, I can Messagebox the user that something is not valid but how can I setfocus to a control or change a controls color?
Your presenter holds a reference to the view anyway, so you can just manipulate the widgets (text boxes etc.) directly from the presenter. Or, possibly better, have a method in the view like nameIsInvalid(), where you write your desired behaviour (changing color, setting focus). This method is called when the presenter notices that the input validation has failed.
The validation itself should be done in the model, since that is view-independent.
As always, you don't need to be super dogmatic about that. If it makes sense to have some simple validation associated directly with the widget, then leave it there. But a final validation of the whole form should be handled as I've described above.
Related
This question must have been solved multiple times by many people, however after several hours of research I still haven't found what I'm looking for.
What I have is a ExportSettings.settings file with a bunch of settings (bools, strings, ints, etc) and I want to create a View for them. In order to do it I've created a simple window in which I've placed standard buttons as OK, Cancel and Close and linked them to a KeyDown event to let the user accept/cancel using Enter/Escape.
I've created in XAML the needed Checkbox, TextBox, etc, for my settings. When the ExportSettingsView class starts, in its constructor I read my settings and assign the value for each control. In past I bound them directly but that unables the cancelation of changes, so I discarded it. When the user clicks OK button I assign, again, code-behind each value for each settings. If he clicks Cancel no assignment is done and the window just closes.
I would like something like EditableObject for my settings to avoid this ugly looking way of making my SettingsView.
Some of the things I'm looking for are:
Being able to put some comments in my settings would be nice (ToolTip)
Autogeneration of controls using reflection?
Avoid creating custom settings class (and the work of saving and reading everytime the application starts/shutsdown)
Break you problem up into parts to use MVVM, create your window and bind it to another class (ViewModel), this class will have properties on it that reflects the data in your settings file. this class also has to implement INotifyPropertyChanged. It can also implement EditableObject if you want, but frankly it isn't needed.
Hook you buttons up to Commands on your VeiwModel so that when the user hits save, it writes its properties to the settings file.
In this instance:
Window is your View
The new class is your ViewModel
Settings file is your Model
This will allow you to cancel changes, just dont write to your settings file when the user hits cancel.
The biggest point is that you DONT bind to your properties settings directly.
If you want auto generated fields for the view youll have to use a property grid, but with MVVM, your view is decoupled from you model so changing from things like textbox and such to a propertygrid would be easy.
When you do a search for MVVM, dont be fooled by people using a lot of terminology, MVVM is a very simple concept, it boils down to three classes, your View (xaml), View Model (what the view binds to) and Model (your data), THATS IT! good luck
I think you need something like this http://wpfdataform.codeplex.com/
And if you use ReSharper you can easily generate wrapper class for your settings
.NET already supports very nice tool for saving application and user variables. http://msdn.microsoft.com/en-us/library/aa730869(v=vs.80).aspx
It has to be saved explicitly so it might suit you very well. You can check what type the variable is and create a suitable control.
In my windows application i have a tab control with many tabs and sub tab controls also, each and every tab has many field like text boxes and list boxes.
i thought to validate every field by clicking button called "NEXT" before changing to nexttab and if any field fails with validation a message box should pop-up with error message and focus should remain in that field. can any one help me with ur suggestions...
validation requirements are required field and only numeric and alphanumeric...
Thanks in advance!!!!
A good way is to create a derived controls with input area and validation logic. Then, it is matter of enumerating hierarchy of controls and see if they are valid based on validation rules applied.
Another way, is to "attach" validation logic to controls. How? A mapping mechanism or use the "Tag" property.
But isn't it better to validate control using "Validate" event, when user tries to exit the control? That will not allow user to supply bunch of trash and hope it can be saved.
How can I check if any control (check box/radio button) of the currently active form has been selected/toggled?
My goal is to create an option called Save changes automatically which would enable saving the current state of check boxes and radio buttons, so I need to know when any control is selected/toggled (to execute the save settings method). I don't want to create a separate event handler for every control, I'm looking for a generic solution if it is possible.
This is not a job for the user interface.
Use databinding to change a Model in code-behind and let the model trigger/escalate changes.
To help you on your way a little:
Your checkboxes and other controls are not where your data is. They should only show the data.
Create an object (the Model) with boolean properties for the checkboxes and int/enum properties for the radioboxes. Set up the databindings from the controls to the properties.
Then you can implement the necessary logic in the Setters of the properties.
As Henk proposed, you could use a Separation of Concerns pattern such as MVC to separate UI and domain logic. As the user makes changes to some UI widget, you update the value in the model, for example by setting a property. The property setters could then update a IsDirty (or HasChanges, ...) field. This property would be read by the UI which would, depending on the value of IsDirty, decide what needs to be done. (Display a MessageBox("Do you want to save your changes") or something else)
I do think that Henk was thinking web while you tagged the question with WinForms. Chances are you are not using a pattern to separate UI and domain logic. (and that UI and domain code are already so intertwined that your current deadline does not allow you to introduce a model right now)
You could achieve the same thing by placing the IsDirty field on your Form and having the Changed EventHandlers set that IsDirty value. By subclassing the Form (ie put the IsDirty on your 'FormBase') and your controls (for example by introducing a watermark), you could have this behavior out of the box for all your forms.
When looking into MVC frameworks for flex, as3, silverlight, and wpf... a common concept of ICommand / commanding keeps appearing... Can anyone explain the advantage of using ICommand / Execute() ?
Where I dont see the value added is - Why can't the controller map the input (ie: a click event) to the correct method inside of the model? I'm assuming it is because commanding buys you something - like removing business logic from the controller / the would-be event handler in the controller.
Thx.
Here's a couple of cases that demonstrate the value commands add:
Suppose you have a simple form with a text box and Submit button. You want a button to become enabled only if some text is entered into the text box. With commands all you have to do is to implement CanExecute method (to return true or false depending on the value in a text field) A framework will automagically disable/enable button accordingly. With code-behind (or controller) approach you'd have to write a code do enable/disable button manually.
Suppose later you decided you don't like the button control you used, and decide to switch to a new control (being that a button, or something more exotic) from a different library. All you have to do is make a change in XAML. Any control that supports Command binding will know what to do. In code-behind approach you'd have also modify your button click handler (since new control will probably require different event handler signature)
Suppose later you decide to add a checkbox to your text field that would visually indicate to user whether the content of that field is acceptable. All you have to do is to bind this new checkbox to your command's CanExecute, and now you have two controls already that would automatically change their visual appearance depending on whether form is submittable. With code-behind approach (or controller) addition of a new control would require adding more code.
Suppose you want to test your action. Since commands don't depend on any visual elements, and don't need them, you can easily write a unit test that will not require user clicking any buttons, or entering any text. With controller approach you'd have emulate controller's events, and mock the view.
Summarizing:
Commands provide a well-defined interface between the business logic and the presentation. Business logic implementor doesn't care about how visually certain action (e.g. command) will be implemented. He simply provides the action implementation and an ability for a presentation to query the state of the action. He doesn't care what particular UI element (or elements) will trigger that action, how exactly (in)ability to execute that action would reflect in UI, and what changes UI might go through in the future. At the same time presentation designer doesn't need to know anything about event handlers, controllers, etc. He has a Command and he plugs it in to any UI element (or elements) he chooses without the need to go to C# code at all.
What controller are you talking about?
The Commanding concept in Silverlight and WPF is used to tie together (through binding mostly) the UI to business logic (be it a controller/viewmodel/model/etc).
That is the point, to move the functionality of the command outside of the UI.
Example. Saving a widget in your application is probably always done the same way. Sure, you might let the user change the name, or this or that, but the overall behavior is always going to be the same. Now, in your application you might actually initiate saving a widget through a lot of different UI avenues such as Page 1 has a button on the right hand side that saves the widget on that page, Page 2 has a menu item on the top that saves the widget on that page. The UI is different but the behavior remains the same.
You can accomplish the same goal by using Event Handling (such as grabbing the click event on a button), but now you're back into the context of dealing with UI specific issues. Commanding, arguably, has a cleaner separation.
The simple answer is that commands are bindable whereas events are not. So if you want to respond to a button click event you can either:
Attach an event handler in the code behind.
Create a click command and bind it to the ViewModel's command.
Since one of the goals of MVVM (which is the more common pattern for Silverlight and WPF over MVC) is to seperate code and UI. So if you take the first approach you end up with code in the View. If you take the second approach you can seperate the code from your view using commands and bindings.
I used an application recently that was awe-inspiring. All the forms inherited from their own classes and a 'form' came with an amazing amount of functionality and looked the nuts.
What I'm interested in is this 'feature' of the form. This was a C# WinForms project and blew me away.
The forms were bound to objects that the group had written to support two-way data binding (to an extent). The way they behaved was pretty simple:
The data input forms all had controls that inherited from textbox and these were bound to properties of an object, Entering data immediately validated it and the box was a light pink if validation failed and a light green if it passed. If the box ever turns blue this actually means the value in the database the form is bound to has changed and your changes to the controls were immediately saved when valid values entered. It was the case that sometimes a section of controls had to be filled before a save occured. But it was all automatic. You could stop at any point and come back later and continue without actually saving yourself.
And like I say if someone else is editing the same record values they change caused your textboxes to become blue and you knew you needed to reload the screen to see up to date information.
All of this came from using their own form class they had written and their own textbox controls bound to an objects property.
I'm mainly wondering how the hell did the object figure out the value had been changed by someone else. It surely isn't polling the database. This system was amazing. The brilliance didn't stop there.
For simplicity. How might I create an object or collection of objects to mimic the bahaviour. I'm not going to but I can't even see how.
Thanks
I'm pretty sure that anything involving other people's changes would have needed to hit the database. For two-way binding, all you really need is change notification - i.e. INotifyPropertyChanged (or a FooChanged event for every Foo property). This is all abstracted into TypeDescriptor - i.e. any binding that uses the regular PropertyDescriptor implementation (which it should) will know about notifications via SupportsChangeEvents, AddValueChanged and RemoveValueChanged.
For validation - IDataErrorInfo is your friend; by implementing this, you can volunteer validation information (which is used and displayed by several controls, such as DataGridView). i.e.
IDataErrorInfo dei = obj as IDataErrorInfo;
if(dei != null) { // supports validation
string err = dei["PropName"]; // or .Error for overall status
bool clean = string.IsNullOrEmpty(err);
}
Note that an alternative approach would be to have a Color property on the data aobject, and bind that directly to the textbox etc.