views:

328

answers:

7

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...

+12  A: 

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.

dnord
+3  A: 

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.

Dror Helper
+3  A: 

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.

Daok
While this is a correct answer, I don't see it being terribly useful to the OP considering the question. Some links to MVC, MVP, and implementation using WinForms would probably be very helpful.
cfeduke
Thank you, but I don't think that implementing MVC type logic in this one circumstance would be very practical at this point.
Ed Swangren
Well it's a case of flexibility -> Effort. (from the least effort) You could just chuck shared code in static methods, have an object shared by the forms and finally (flexibility++) an object that OWNs the forms instead (Controller).
Quibblesome
well the accepted answer is exactly what I wrote 1 hour ago : having a "controller" that save, valid and all other stuff you require that shouldn't be in the view (WinForm). I might haven't enough explain...
Daok
It is. Truthfully, while I know the basics of MVC, I have never used it formally. I still gave you +1 for helping.
Ed Swangren
+1  A: 

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:

  1. 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.
  2. Create a helper class with common functions. Generalize the logic on the two forms to call this helper class for common functions.
  3. 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.
  4. Create custom controls that are specific to the type of data with which you are working, and use those controls on the two forms.
Jason Jackson
+1  A: 

It sounds to me like this is an excellent example of binding oriented programming. Paul Stovell has an excellent treatment of the subject here:

http://www.paulstovell.com/blog/searchquery-windows-forms-binding-oriented-programming-example

The link appears to be dead atm, so try the google cached version.

Gavin Miller
A: 

Thanks everyone, I decided to use an object that can keep track of all of the pertinent logic. There is a small amount of duplication in the form of a couple of properties, but this helped a lot. Thanks everyone.

Ed Swangren
+1  A: 

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.

wegrata