views:

1004

answers:

4

Hey everyone!

I am developing a desktop application with a MainForm that's grown rather large. There are lots controls in several containers on different levels (SplitContainers, TabPages, Panels).

Now I want to refactor this class by separating all the controller code responsible for data binding & clearing the controls or carrying out user interactions into separate Controller classes.

[EDIT]

Purpose

The purpose of this application is to track orders (called Job) and their positions (called Jobitem). Each Job is related to a customer, each Jobitem to an Article (Jobitems contain information that's specific to the manufacturing process of its article, therefore it's wrapping the article). Job, Jobitem, Customer and Article have dynamic properties (basicalyl key/value pairings) which are managed by a PropertyManager class.

Architecture

My application is split into 2 main projects: The core contains the data model in 3 LinqToSQL DataContext Classes:

  • ArticleManagement
  • JobManagement
  • PropertyManagement

For every DataContext class there is a XyzManager class which provides the LinqToSQL Object in a Collection to the GUI, encapsulating the LinqToSQL data source. It also handles creation, deletion and modification to its corresponding DataContext types.

Then I've got a GUI project, naturally containing a main form and some additional forms for stuff like options etc. As of now, my GUI project holds a reference to each XyzManager class and gets & sets the data through the Manager classes as the user interactions dictate, containing all the controlling logic.

I've put most of the independent logic for this into a static Utility class outside of the main form class, but that's an less than ideal approach I guess.

[/EDIT]

This is my first bigger Desktop Application and I am having a hard time encapsulating the GUI. As of right now, all the controller code responsible for handling user interactions resides within the MainForm class.

I know about the MVC pattern but I'm not sure how to apply it on a C# WinForm with my current design.

My custom code alone is over 2400 lines of code long, not counting in the automatic generated code of the form, with a rising tendency. I want to refactor this, but am lost as to how I could solve this in a more elegant fashion.

A: 

Look at the Composite UI Application Block.

RichardOD
+2  A: 

Normally I try to compose a complex GUI by using smaller UserControls. But a few points are very important:

  • Each of these UserControls should be independent (especially from the Form)
  • UserControls that have the purpuse to show or change certain data should depend only on this data. You should try to implement your controls in a way that they can be bound to a DataSource that serves all data the control needs.
  • When you need to hand over informations to the parent container (another UserControl or the Form) use events to which the container can subscribe.
  • When you use (context-)menus, check if they are bound to certain items. You should create the menus near to the items and not within the UserControls. So, when you show the same item on the GUI in different views (controls) more than once, every item should have the same contextmenu.
  • Try to apply a command pattern for actions of buttons/menus.

Your solutions sounds like you could not seperate the different responsiblities until now. Just dividing the code into different controls without clear borders and responsibilities is not enough.

tanascius
So what do you suggest to separate the different responsilibites? I've edited the main post with some more explanations on my architecture.
Michael Barth
+2  A: 

For small scale applications you should take a look at Model-View-Presenter (MVP), there is a good presentation of the (in my opinion) best way to do MVP: http://martinfowler.com/eaaDev/SupervisingPresenter.html

khebbie
Thanks for the link. Martin Fowler states at the end, that the Supervising Presenter is good when you want to test your GUI, but not that good in separating the controller from the view, so it's not the thing I'm looking for since separating is my main goal. Testability isn't an issue. Presentation Model sounds more fit for this goal.
Michael Barth
Accepted as answer since the link pointed me into the right direction. Though I'm using the Passive View (http://martinfowler.com/eaaDev/PassiveScreen.html) now as solution.
Michael Barth
A: 

Do you use JobController only for one form? If yes, then maybe all you need, is to split behind code into several files using partial keyword?

arbiter
Right now, yes. But I want a flexible Design since this project is going to get more complex soon. Also, splitting the Code over several class files does not ease the fact that it's a big class, as a fellow developer would have to check several files instead of scrolling one big file. That's no good, either. :/
Michael Barth
Then you definitely can look into composite ui appblock. However i do not like it personally, because for many projects it has opposite effect (confusing developers instead of simplifying things). And in general 2.4k lines is not too much :)From my point of view it is better to look for some sort of command pattern.
arbiter
Yeah, I don't think Composite UI AppBlock is the right solution for me, either. Having a look at some variations of the MVC right now, hopefully I'll find something there. I know that 2.4k isn't too much, but I expect this class to grow as the project keeps going on. Better find a flexible soultion now than later. ;)
Michael Barth