I have two forms, form A and form B. These forms must differ in appearance, but they share a lot of logic. The problem is that this logic is tied to the appearance (validation on button click, events being fired, etc.). For example, I have a name field, and when the save button is pressed, I need to fire an event which causes the parent form to validate the record name to avoid duplicates. Both forms need this logic, but their save buttons are in different places, and the tooltip that is shown when an error occurs also needs to appear in a different place. This is just one example, but does anyone know of a way that I can avoid copying and pasting code here? Perhaps I am missing something obvious...
You could create an object with data that is represented in both forms, and put validation logic in that object. The presentation layer should populate that object with the entered data, ask the object to validate itself, and then handle validation errors in a form-specific way.
If the common logic is UI related you need to create your own custom form class (that inherit from Form class) with the desired logic. then all you need to do is inherit that class in your forms.
If the common logic is less UI related create an internal class that encapsulates the common logic and call it from both forms.
You need to add a Controller between your 2 views and your shared model. This way you will just need to do : myController.save(); instead having to call you model object to save them in both winform.
There are few ways that I can think of to refactor these forms to share logic. You could use one or more of these in conjunction:
Create UI specific "bean" objects that wrap your business object and adds additional functionality that is shared between forms. This bean can do things like create tool tips, assist with validation, eventing, etc.
Create a helper class with common functions. Generalize the logic on the two forms to call this helper class for common functions.
Enhance your business objects to do your validation. I don't mean to say your BOs should be aware of any UI, but they could/should enforce the business rules. This might pull some of the validation logic off your forms and into a common location.
Create custom controls that are specific to the type of data with which you are working, and use those controls on the two forms.
You may also want to take a look at the CSLA Framework, I've used it pretty successfully in past projects to help reduce the amount of duplicate code between different UIs. It takes advantage of .NET's databinding capabilities, but I don't think it's required to use databinding just to get the most out of the framework.
Related
So I've just started developing C# WinForm applications and each project I've been working on seems to be larger and requires more user functionality. If I add all of the functionality to one form, obviously it can get out of control very quickly. My last project I would divide up the functionality into individual Forms, and whenever someone say wanted to perform "Feature1" I would instantiate Feature1 Form and show it as a dialog with the main Form as it's owner (so they couldn't click off it).
I'm just curious of what other methods are out there for keeping code organized within Forms. If you are forced to have tons of features/functionality on a single form is there a good way to keep items organized? I simply hate having a code file with hundreds/thousands of lines long.
The answer may simply be in the design, try to design the UI up front so you can utilize multiple forms?
Another example I faced. I created a Tab Control and had about 5 tabs. Those 5 tabs had tons of features and were all stored in the same CS file. What other options did I have? Create a new custom TabControl class with my specific functionality for that tab in it?
I don't mind reading, so if there are decent articles out there feel free to link them!
The go-to method is a Controller/Presenter. The idea is that the window should only be responsible for actually handling the UI events of its controls, and it should do so by calling methods on a Controller which do the real work for the window. The window can either have the handlers necessary or it may link the UI events directly to Controller methods; the former is usually the easier method, but it can be tempting to sneak in a line of code here or there that really should be in the Controller method. By doing this, you sever the layout and presentation logic in the Form class with the business logic in the Controller.
Mark Hall's suggestion of User Controls is also a good one. By creating UserControl classes for tabs or for common UI control combinations, you sever the logic responsible for laying out that part of the UI from the main form's code, and the control then just "drops in" and the window works with it in a much simpler way. This is a must for implementing custom but reusable controls; the fundamental tenet of DRY is that if you have two lines of code in two different places doing the same job to two different but interchangeable things, those lines of code should be merged into one place.
I have used UserControls in my projects to group functionality into separate objects that can then be added to your Form.
I tend to split my logic code from the UI as recommended. If you do this, you need to be somewhat cautious with how calls are made across the application to avoid Cross Thread Exceptions. I was taught to create delegates and events to update the UI from the logic class, but MSDN of course also has a lot of information on making thread safe calls.
I know this is a late answer, but if anyone still reads this question, another way to reduce the number of lines of code in your form is to use Data Bindings. If you are using properties, Data Bindings make it so that you don't have to constantly write handlers just to do something like PropertyName = textBox.Text;. Data Bindings work with both datasets and objects.
I'm writing a flashcard program and am running into an issue I always seem to face when writing this sort of Forms program.
I'll describe the program then the issue.
In this program, one main form controls almost all of the action. Depending on the user's input and form events, different buttons/controls may become enabled or disabled, text in various boxes may be populated, etc.
For example:
Some questions might be multiple choice and others require typed input.
The user inputs their answer and clicks a button -- if they get something wrong, they have the option to override the 'wrong answer' judgement and say it was really a different, correct variant.
Statistics regarding which questions were answered correctly are kept and used in the decision about what flash cards to show next.
Now the issue.
How do I best create a clean interaction between the "form" code (for example, handling the OK button's onclick command, and enabling or disabling various controls) and the "logic" code (underlying data stores, program logic that does not have immediate implications for display)? If it is all mixed together in the form object code it does not seem right.
Can anyone suggest a design pattern (especially one widely used) that manages this cleanly?
In case it is relevant I am thinking of something like this:
Object Model:
Class MyForm: the form itself.
Class FormController:
Child class of MyForm.
Instantiation requires an object of type MyForm.
FormController's job is to put its MyForm object into a particular "state," by enabling/disabling controls, displaying various text, etc.
FormController exposes a small set of public functions which deal with semantically high-level request for the form state (such as "DisplayNewQuestion(QuestionData d)")
Class Session: Contains all underlying persistent data or objects involving this session, including lists of possible questions, objects that select the next question from the list, etc.
Class Driver: Drives both the Session and FormController objects. For example, it would ask the Session object for a new question, and pass it to the FormController object to update the form.
The advantage to something like this is that icky form code and nice logic code are now completely separable. But is it worthwhile? Are there better or more common design patterns for this?
Thanks a ton!
I am always most comfortable with Model View Controller in this situation. The Shade Tree Developer wrote the most informed series I have ever read on the subject, see here
The jist of MVC is
Model contains the data to be displayed
View is your form and only has logic for displaying and informing of user interactions
Controller contains the glue to make it all happen, including the business logic.
The depenencies should be
Model doesnt know about the view or the controller
View knows about the model and knows how to extract data from it to display
Controller knows about the Model and the view, instansiates them both and wires them together.
The model raises an event when it changes, the view captures this event and refreshes its display accordingly.
The view raises an event when a user interaction occurs, the controller captures this event and performs the correct action for the interaction whether that be updating the model or saving or clearing or whatever.
The view should not write to the model itself
You will see a lot of code where the form creates the controller but imo this is wrong. It came about because of people trying to apply this pattern in asp.net webforms where you have no control over the lifecycle, the first thing that always got created was a view so you had no choice but to have this create your controller, however in winforms you are in control, so make it clean, have the controller create the view.
You might want to use the Model-View-Controller (MVC) design pattern, in which the "logic" is your controller and the "view" is your UI. The model is used to access and retrieve data from your data source (a SQL database for instance)
It is worthwhile to separate your logic from your UI, because it makes them more maintainable. For example, if you want to change your UI from a winform to a web page, you don't have to redo all your logic.
Also, it makes up for a really cleaner code. Using design patterns in general helps other programmers understand your code faster as well.
I have WinForm which is a tab based and including all Tabs it has around 60 UI Components. Depending upon value selected in some UI Components i am Auto filling rest of the UI components.For this i would like to write a helper class.But the problem is if i pass Winform object to that class i am not able to access values on that Form because all the member are declared private.
one possible solution is that I can write around 60 properties in the Winform but i think this is not the best way to do it. I would like to know what is the best way to handle problem like these ?
You could change the Modifiers for your UI components from private to internal. This would allow all classes within the same project to directly access the components.
However, I would argue that exposing the necessary components through properties is a better design than exposing them publically/internally. I acknowledge that it includes a fair amount of typing, but it's safer as you can expose them cleanly, in a manner specific to your use case.
That being said - there are a couple of things I would consider:
Can this be refactored into a smaller class, using fewer components by using UserControls? This might make it more managable, as well as promote reuse. 60 UI elements is a fair amount for a single screen.
Can you refactor this to pass the data, instead of trying to work with the controls directly? For example, you could auto-fill the data via a shared interface, and data bind the controls to the data, or something similar.
You can declare the members of a WinForm as public protected, protected internal, and internal. You can do this either in the properties window for a specific component (go to the Modifiers property) or you can change them in the Designer of the form (they are declared after the "Windows Form Designer generated code").
If you don't want to make the members public, nor make a property or method to get that information, then all you're left with is attempting to get the value via reflection, which is perhaps the worst option of all three.
Your best solution would be to make properties for each of those private members and expose them that way.
One way to approach this is to create a class that contains all of the data that you want to bind to (e.g. a class that implements INotifyPropertyChanged).
Then share this instance between the WinForm and the other class. Voila!
What is the best way to do validation in a windows forms application?
What is the easiest way?
What is the most attractive (to the end user) way?
Regards,
-Kushan-
Concerning UI validation, I have a set of control validators, and I just plug 'em in where I need them by assigning their control. You can show errors using ErrorProvider, all you need is encapsulated framework to automate things.
First there is the ValidatorBase class. Make it abstract and inherit the Component class so you can have design time support. Store a private instance of ErrorProvider here, and use something like Template Method pattern (create a Validate method, which in turn calls the protected abstract DoValidation method). In concrete implementations of the base class just override the DoValidation and put your logic here. You can have EmptyValidator (check if control's value isn't empty), RegexValidator (check controls value with some reg. expression), GroupValidator (do Validate on every ValidatorBase instance in some list), whatever you want.
In the base class, you can add things like design-time support for properties (the error message, icon, control to validate etc...)
EDIT1: Now, concerning validation other then in the UI, that is the domain of your business layer, and your rules. There are frameworks / patterns for those things too, but I think you are asking about the UI validation.
EDIT2: ASP.NET has a set of similar validators built-in, although with more functionalities (client side validation, etc...), but to be honest, I don't like them that much.
EDIT3: also check:
Is there any validation control available in .net win forms like asp.net web form?
One interface you might consider looking at is IDataErrorInfo along with the ErrorProvider class. I've got an old blog post that provides a list of the DataBinding classes and interfaces that might help: Data Binding Classes, Interfaces, and Attributes in Windows Forms 2.0.
What is the best way to write the code ?
(1) Like directly writing the code in the button_click() event.
or
(2) Make the function of that code which I write in button_click() event and write this function in one class and then that function I should call in the button_Click() event.Like is it called three-tier approach to write the code ?
Like in button_Click() event I write the code to save the records in csv file from datatable.So I should write that code in button_Click() event or I should make one new function and one new class and write that code in that function which is the new class and calling that function in button_Click() event.
This is only one example but I am talking about all the code written in my application that which is the appropriate and best way to write the code and what are the benefits ? Note that I write the code in Winforms with c#.
You should go for the separate function in a different class. You should do that because you'll make the code reusable and create a decent separation between the user interface and application logic. Like this, you could for example change the UI without affecting the rest of the application.
Also take a look at MVC pattern, you'll understand better the whole idea.
The only situation where i think that the first option should be used is when it does some action that will affect the UI, and still i'll create this in a separate function inside the Form class.
If it's affecting the UI, it should be in the same class because it's related and for example if it's a code to refresh a grid i'll put this in a separate method inside the same Form class because this could be used in different places inside it. So changing the UI has no impact on the application, you just make your code reusable & maintainable.
It all depends on situation.
If you are going to make updates to the Form, then it's better to have the updating code in the Form. However, if there are lots of processing, then surely it's better design to have a separate class handle the job.
It all depends on situation.
Generally, you don't want any logic in the event handler, since GUIs tend to provide redundant mechanisms (context menu, menu bar, toolbar, accelerator key) for triggering the same command, and the event signatures aren't compatible for all of these. Then the question becomes whether your common function should go in the Form class or into the data model.
I often start out with the logic in the Form and then refactor it into model classes as needed. Many small apps will never get large enough that multiple classes are required for maintainability. As long as you avoid code duplication (i.e. copy+paste) then refactoring will be straightforward later if you find you need it.
It is always good to develop classes for jobs. As it makes your code reusable and it also implement three tier Architecture. The benefit is that it is easy to understand.
The important thing is that, it is only beneficial if you develop your classes appropriately. Develop methods in the class which can be reusable for you.
The another benefit is that it hides the complexity of your code.
There are two general approaches to adding structure to code: top down and bottom up. Top down structure comes from design work that can involve a formal or informal process and pure design artifacts like UML diagrams or functional specs. The ultimate goal in a top down process is to create classes and interfaces in your code that will provide appropriate structure to make your code maintainable. This can happen before you write the code, or as part of an iteration, but the idea is that you create the structure first, then create the code.
Bottom up structure comes from refactoring. For example, start with all your logic in a button click. When you add a menu item that does the same thing as the button click, move the code for your button click function into a private member function on the form. When you need the same features in a different part of the application, encapsulate the code and state variables used by your private member function into a class.
I'd recommend using both approaches. The right mix for your situation depends on the development team (size, location, ability to communicate) and the size of your application. Generally speaking, large applications require more top down, and on very small applications a minimal amount of top down design is adequate. But there should always be some high level planning, even for a small app.