views:

129

answers:

6

Hello people,

I'm about to create WPF application. So far at uni the only way we have ever done GUIs is to have one main window with one code-behind file for handling its button clicks etc..

My issue is that as the application grows, the GUI grows, and the size of the code behind file can get really out of hand!

I have identified about 15 main use cases for my system (example: enter details, view details, etc...). I am creating a main window (size: 480x320) that consists of 15 seperate screens (one for each use case). This could be achieved with a centered and stretched TabControl, with 15 TabItem's. Or more likely it could just be a bunch of layered containers, one on top of the other (only one visible at a time).

The point is, with 15 seperate screens, my code-behind file will become enormous (not to mention the xaml file!): Juggling between states - making 14 collapsed/hidden and making one visible, Handling the controls for 15 different screens.

Is there a way to having 15 seperate forms, each with its own code-behind file, instead of 15 TabItems on the one form, and then having one main engine creating and scrapping them as needed? Ofcourse, it should appear as though it is one form, not 15 pop ups.

How do i deal with this? How would you deal with the issue of xaml and code-behind files that are thousands of lines long?

+1  A: 

You should create each screen as UserControl and reference that in your MainWindow xaml.

However, it seems like you have an enormous design flaw in your application, i.e. having your logic in the UI. The code-behind file is not there to drive your application or logic, it is there to drive your UI! You might want to have a look into the MVC pattern and Dependency Injection to solve this.

The Wpf Application Framework would be a start for that.

Femaref
+1 for suggesting a better methodology
Tim Joseph
some handler will be responsible for all logic, or will be in a dll reference.. i just thought it would be nice/consistent to also split the gui up by the use cases i came up with in analysis.
Mikey
p.s. ill look at UserControl and let you know, thanks!!
Mikey
A: 

In terms of the code-behind files, you could use #region tags to allow you to collapse and expand the different screens... Although, splitting it out logically is a better approach if possible

Tim Joseph
I've encountered this before and it always strikes me as akin to sweeping dirt under the rug.
Dan Bryant
I disagree, it helps you logically sort your code - group your event handlers, your properties etc.
Tim Joseph
@Tim, regions are helpful when the class becomes sufficiently large, but if it's large enough that regions are indispensable, then it probably means that the class is in need of refactoring. The case that I've encountered is where you open a file and it looks like it fits on two screens. Then you expand a few regions; okay, now it's maybe a dozen. Oh, but wait, there were regions inside those regions; in fact, those 'two' screens had thousands of lines. All this code in one class created numerous opportunities for tight coupling and now it's difficult to test any one piece in isolation.
Dan Bryant
A: 

You could make your class partial and split it up into separate files.

rmx
+4  A: 

If you are about to start using WPF you should definitely have a look at the MVVM design pattern and commanding. You should also consider using dependency injection, via a IOC container, it is pretty easy to set up, this is a great tutorial.

In your example, it would be possible to create a single view (user control) that appears on a relevant tab page, that view would have its own related view model class that provide the data and handle any interaction via commands. Each view model would be bound to its view via the IOC container, thus making it easier to change the behavior of the user interface.

Rohan West
A: 

The WPF Composite Application Guidance (or Prism) uses the concept of UI Composition to handle breaking the UI down to smaller classes.

http://compositewpf.codeplex.com/

Cameron MacFarland
+1  A: 

Your instincts are good: you don't want to put everything in one Window. You would be far better off putting each of the 15 "screens" in its own XAML file, as either user controls, or pages.

If Web-browser-style navigation would make sense for your application, then look at the Page class. If you set your Application's StartupUri to point to a Page (instead of a Window), then you'll automatically get a window with Back and Forward buttons, and you can use Hyperlinks (set the NavigateUri property to point to another Page) or the methods of NavigationService to navigate to new pages.

If you don't want the Back and Forward buttons, then put each "screen" in its own UserControl, and add some minimal logic to the main Window to show and hide them. Or if you're using MVVM, you could set up some magic where you just change your Window's DataContext (or better yet, a property on your application-level ViewModel) and it automatically loads and shows the correct UserControl (look into DataTemplates, or watch the video below).

I would also strongly recommend that you use MVVM to try to write as little codebehind as possible (ideally none at all -- not always achievable, but you'll learn a lot by trying). That makes your XAML tons easier to refactor. If you later decide that one of your Grids has way too much stuff on it, you can just cut and paste it into a new UserControl, without needing to spend tons of time disentangling all the codebehind.

Since it sounds like you're not familiar with the MVVM pattern, this video might go over your head, but I can't help recommending the MIX2010 talk "Build Your Own MVVM Framework". It's an eye-opener on what MVVM can do, and has some solid ideas on how to manage navigation between different UserControls. (It also has a link to an intro-to-MVVM talk.)

Joe White