Design Patterns for C# Windows Forms - c#

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.

Related

Organization with WinForms

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.

What exactly is GRASP's Controller about?

What is the idea behind Grasp's Controller pattern?
My current interpretation is that sometimes you want to achieve something that needs to use a couple of classes but none of those classes could or has access to the information needed to do it, so you create a new class that does the job, having references to all the needed classes(this is, could be the information expert).
Is this a correct view of what Grasp's Controller is about?
Generally when googling or SO'ing controller, I just get results about MVC's (and whatnot) which are topics that I don't understand about, so I'd like answers that don't assume I know ASP.NET's MVC or something :(
Thanks
According to Wikipedia:
A Controller object is a non-user interface object responsible for receiving or handling a system event.
From Applying UML and Patterns:
What first object beyond the UI layer first receives and coordinates ("controls") a system operation?
Controllers, across the board - be it in MVC or GRASP or Patterns of EAA - are all about receiving input and responding to events.
I conceptualize it very literally: think of a video game controller.
It responds to input events - the user pressing buttons. It doesn't necessarily know what to do when you hit a button, but it at least receives the event.
Looking at the controller, one can easily figure out what the system events are - that is to say what inputs it responds to and how the user interacts with the system. On a Nintendo Controller, it's evident that system events are:
Press A
Press B
Press X
Press Y
Press ↑
Press ↓
Press →
Press ←
Press L
Press R
If we were to take all these events and build a software controller to deal with them, it would be an MVC controller: these events are all concerned with the physical controller as presented to the user - it's "view", if you will. But there's a second layer of input events for most video games, where button mashing maps on to specific system operations. For example, if you're playing as Scorpion in Mortal Kombat 2, pressing ← ← B triggers one of your special moves. In that case, the system could need different controllers which deal with these different kinds of events:
Here, the NES Button Controller is a MVC controller which would keep track of the state of UI elements - for example, remembering what buttons were pressed in what order. Depending on application state (see Application Controller - another one!) the NES Button Controller would response to certain button combinations by invoking methods on the other controllers - for example the Scorpion Controller - which are Use Case Controllers.
What's important is that by looking at the design of these controller objects, you can quickly and easily enumerate the system events they respond to.
Altogether, in the end, the MVC Controller is still a kind of GRASP Controller - as its methods tend to represent system events, which respond to user input. But there are other GRASP controllers which are not MVC controllers: Use Case controllers. A GRASP Use Case controller might respond to system events such as "user creates a new sale" while an MVC controller would respond to events like "system receives a PUT request for /sales/new" or "a java.awt.event.ActionEvent fires`".
Models contain data. Views present the data.
Views listen to models, using the Gang of Four Listener pattern.
Controllers decide what to do with the user input. Either they call methods on the models, construct new objects in the current Set of models, remove objects from the current Set of models, rewire views to different models, add views, remove views, or reconfigure views.
GRASP is just a tool to better understand software, and hopefully prevent one from making blatant mistakes in the creation of new software through good design practices. It really has nothing to do with MVC, but it can be used to better understand MVC.
The key in MVC is that the model isn't polluted with code that handles display details. That way you can isolate the "business logic" or "what the class is supposed to do" inside the model alone. Views react to changes in the model because the model emits messages to each view which has registered itself against the model (the listener pattern). The messages are often quite terse, basically the don't need to contain any data other than "the model has changed".
When the views get notified that a change has occurred in the model, the view then acquires the necessary data from the model's public interface. Once the view has the data it needs, it displays the data to the user (using whatever interface the view was meant to support). This isolates the presentation of the data to a class which will break when the view changes incompatibly, and allows modification of the view code without the model class requiring "compatibility" modifications.
The controller is responsible for knowing where the focus lies, and which model or view to update. It's the glue that puts things together, and is responsible for correct handling of input.

MVP and presenter granularity

We've been using the MVP pattern and Winforms with a fair amount of success. However, a question always pops-up about MVP:
What is a good granularity for presenters?
What I mean by that is: With Winforms, a fine-granularity usually works quite well for user controls. That way, it's easy to reuse user controls and use them as building blocks while designing more complex GUIs. However, having the same (fine-)granularity with presenters seems to be a problem.
On one hand, having coarse-grained presenters hinders the ability to use "plug-in" controls and it sorts of violate the DRY principle: Multiple presenters often need to implement the same logic (populate a list of customers, for instance), which is used by multiple, more complex, controls.
On the other hand, fine-grained presenters seem to limit the ability to reuse controls in different situations. For instance, an editing view might sometimes need to save the customer right away; sometimes it needs to link it to something else; sometimes is just needs to validate it; and so on. It often depends on the more complex control. But there's also a fair amount of shared behaviour.
Note that, in both cases, 1-presenter-1-view is achievable. What is considered "1-view" changes.
What is usually considered best-practices for presenter granularity using MVP and Winforms?
Fine-grained presenters and customizable behaviour through options or something of that nature?
Coarse-grained presenters and low presenter reusability?
Something else?
Disclaimer: We mainly use Supervising Controller but I think it also applies to Passive View. Sorry for the long question, too.
We use MVP at all of our clients and this is definitely a conversation that comes up in more than one occasion. How clean should our code behind classes and presenters be? Having said that, we have chosen to use the coarse-grained presenter approach. Basically, every form would have its own presenter and would only get and set properties of any of the controls on a particular form using its view. Populating controls-a call to a db to populate a combobox for example-is located in a public service class. Any validation of user inputted data is located in a BO class which can be reused by any and/or all of the presenters. I hope this helps.
In my CAD-CAM system my presenters don't use user controls. User controls reside in the view which reside in a EXE assembly that implement the view interfaces the presenter use.
If want to display a list of customers I hand it off to the view which has a DisplayCustomerList and it uses whatever combination of user controls it needs to display the customer list. If multiple views show the customer list in the same way then in the ExE/View assembly they share a user control or class for doing that. That class doesn't go outside of that assembly.
Our software is adapted to run many different types of metal cutting machine. So we place a lot of emphasis on being able to rip off the UI and replace it with a completely different UI (corresponding to a different machine). All of these UIs reference the same set of core assemblies.
The hierarchy looks like this
View EXE
Presenter Implementation
Command Assembly - commands are executed by the presenter that modify the model
Presenter Interfaces
Model Assemblies
Off to the side are loadable assemblies that define dynamic content like what file types can be loaded, reports, cutting device drivers, etc. These implement various interfaces found in the model assemblies
One thing I do is that I don't impelment a view presenter for every dialog. If the dialog is tightly bound with a command then it is defined, created, and used along side the command class. Occasionally a group of related commands will share a dialog (File handling for example).
The essential question I ask when using MVP is "What happens if want to completely replace the forms with something else?". The answers to that question will identify where you are too dependent on a particular user control or form engine.
The biggest problem (and one that I haven't got a good answer for) of my setup is that current IDEs and langauges make it very easy to tie user controls to database records. It is so productive compared any other setup it tends to dominate the design. I haven't had to deal with the issue much in my CAD-CAM application so I don't have any answer other than passing the dataset to the view and let it handle it. This site has some patterns that may be of use in this situation.

How to avoid duplicating logic on two similar WinForms?

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.

How to apply the MVC pattern to GUI development

I am primary a web developer but I do have a very good understanding of C++ and C#. However, recently I have writing a GUI application and I have started to get lost in how to handle the relationship between my controller and view logic. In PHP it was very easy - and I could write my own MVC pattern with my eyes closed - mainly because of how PHP is stateless and you regenerate the entire form per request. But in application programming languages I get lost very quickly.
My question is: how would I separate my controller from view? Should the view attach to events from the controller - or should the view implement an interface that the controller interacts with?
If I was you I would expose events from an interface of your view. This would allow you to make the controller central to the entire interaction.
The controller would load first and instantiate the view, I would use dependency injection so that you don't create a dependency on the view itself but only on the interface.
The controller would access the model and load data into the view.
The controller would bind to events defined on the view interface.
The controller would then handle saving of data back to the model via an event.
If you wanted to you could also use an event broker which would void the need to declare an interface per view. This way you could bind to events through attributes.
This would leave you with the Controller being dependent on the model and the view interface, the view being dependent on the data only and the model having no dependencies.
Some examples of the above design thinking can be found in CAB and the Smart Client Software Factory Link To Smart Client. They use the MVP pattern but it could equally easily be applied to the MVC pattern.
Most every GUI framework (from MFC to SWT to whatever) is already MVC based. In fact, the MVC pattern was first created by Smalltalk-80 and later first really used for GUI development.
Double check and look at the standards and suggested practices for your GUI toolkit of choice. Sometimes MVC won't be a good pattern to work with when solving a certain problem or working with a particular toolkit.
Remember: MVC is a great pattern but isn't a one size fits all solution, don't try and force a problem into MVC when event-based or functional style programming will make your life easier.
Imagine this GUI:
The Zergling unit is presented to the user as an alien icon. You can see that it is in its idle animation. Call this the View.
The player moves the unit by clicking on it and a target location. You can subtitute the player for an AI if you want. Call this the Controller.
The HP and attack range of the unit is calculated every game frame when the unit is in combat. You can change this data to make the Zergling into a range unit. Call this the Model.
Keep this analogy in mind and extend it for your MVC designs.
The imortant thing for you to remember, is that in your MVC setup the Controller must know which View to call, but the View must know nothing of the Controller.
So your View must provide a generalized way for Controllers to interact with it, so that you can have several different Controllers call the same View (a standardized graphical output of some data provided as parameter, for example).
This gives you flexibility:
If your customer wants PDF output of
something you only provide HTML
output for, you can get away with
writing a new PDF View to be called
from the Controller with the same
parameters as the HTML View.
If your customer wants similar HTML output of a different data source (say), you can get away with coding a new Controller that provides a different data set to the same old HTML View, which gives the same HTML report just with other data.
If you keep your View detached from specific Controllers, and put the knowledge about which View to call from your Controller, you're well on your way.
Your controller should definately bind to events defined on an interface the view implements.
How you go about doing this can be the tricky part. Dependency injection? A view factory? Have the view instantiate the controller it wants? It really depends on how complex the application is going to be.
For something really quick and simple I would start with having each view construct it's controller and then look at other options if it needed to get bigger. Personally I think a full dependency injection framework is overkill for half a dozen forms :]

Categories

Resources