tags:

views:

850

answers:

7

Any thoughts,recommendations, patterns on a good way to manage an app with multiple forms.

First page is login, that loads a "main form", from there a user could launch a number of other "sub forms" (could grow over time). User should be able to cancel out of whole app at any point.

I know the way I do it right now is not always elegant.

Cody

+1  A: 

I like an Explorer-style interface: Use a splitter in the main form. Use a list control or tree control in the left side, and add a reference to each sub-form as a tag on an item. When the user clicks on the item, push the sub-form from the tag to the right side of the splitter.

You can monitor the select changed event on the list/tree to do form-level validation.

XXXXX
+3  A: 

Consider using the DockPanel Suite. It allows you to create multiple form, and have a complete docking panel solution for you application.

Am
A: 

You can use MDI. To do this, set the IsMdiContainer property of the parent from to true, and set the MdiParent property of each child from to the parent from before the child form is shown. You can then use an MdiList menu to automatically list all of the child forms.

Alternatively, you can use tabs; this is easiest to do with a third-party framework.

Finally, you could do it normally by calling the Show method of each child form with the parent form as a parameter.

For a more detailed and specific answer, please provide more details.

SLaks
Classic MDI is no longer an option for me, though DockPanel Suite is just an improved MDI in fact :)
Lex Li
A: 

I use a navigation-style UI for that sort of thing. Check out this article on MSDN which describes a WinForms framework for "inductive UI" applications.

Matt Hamilton
+1  A: 

There's nothing fundamentally wrong with how you've set things up, but I would change the relationship between your login form and your main form so that your main form isn't loaded by your login form.

In the Main method in your Program.cs file, replace this (presumed) line:

Application.Run(new LoginForm());

with something like this:

LoginForm login = new LoginForm();
DialogResult result = login.ShowDialog();
login.Dispose();
if (result != DialogResult.Cancel)
{
    Application.Run(new MainForm());
}

Rewrite your LoginForm so that it just returns DialogResult.OK if the login is successful (this.DialogResult = DialogResult.OK), instead of loading and showing an instance of MainForm.

From that point on, there's nothing wrong with loading and showing additional forms from MainForm, provided that a user interface like that makes sense for your program (like, for example, a graphics editing program that incorporates various other floating tool windows as needed).

The user can "cancel out" of your entire application by just closing the main form, which is quite normal behavior for a Windows program.

MusiGenesis
A: 

"to manage an app with multiple forms."

Hi Cody,

Tip : do keep in mind that you have access to a very handy way to know, at all times (in any context where you are using the System.Windows.Forms library) the number of open forms in the Application via :

Application.OpenForms.Count

I think a lot depends on what exactly you mean by "manage" your multiple forms, and by what you mean by the term "sub-forms." I'm assuming you're already familiar with the built-in MDI multiple window facility in .NET, and looking for an alternative to that, or you wouldn't be asking this question. Please correct me if my assumptions are wrong.

If you mean by "sub-forms" : forms created within the scope of your "Main Form," then they will, of course, be disposed when the Main Form is closed.

I personally like the "multiple independent window" model in WinForms sometimes referred to as SDI+ (I think it was Chris Sells that coined this acronym).

I like to start by "hi-jacking" the standard Program.cs file so the Main procedure looks like this :

    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Initializer.Initialize();
        // it's now your responsibility to shut down the application !
        Application.Run();
    }

Where 'Intializer is a public static class with one public static method 'Intialize; it might look something like this :

 public static class Initializer
 {
    public static StartFormTemplate StartForm;

    public static MainFormTemplate MainForm;

    public static void Initialize()
    {
        MainForm = new MainFormTemplate();
        MainForm.FormClosing += new FormClosingEventHandler(FormClosing);
        // StartForm will display MainForm in this case
        // MainForm.Show();

        StartForm = new StartFormTemplate();
        StartForm.FormClosing += new FormClosingEventHandler(FormClosing);
        StartForm.Show(); 
    }
  }

Every form created within the scope of the Initializer class is going to be an "indepedent window" (effectively with : Parent == null).

The interesting "business" in this model is the logic in the FormClosing event (not shown here) which, in this example, both StartForm and MainForm share. You can easily test for the Mainform closing by taking the 'sender parameter of the FormClosing call and comparing to MainForm :

MainForm == sender

And you can use Application.OpenForms.Count to detect when there is only one "independent" window left to close. The tricky part is making sure you detect the cases where you want to keep the MainWindow open and handle those first, cancelling the FormClose event as necessary.

I think that's enough for starters : this may be a "primrose path" you don't really wish to go down :)

best, Bill

BillW
I'm curious to know why anyone would do something like what you describe.
MusiGenesis
+1  A: 

I would recommend the Smart Client UI Application Block.

The Block is designed to help you build complex, WinForm–based solutions. It provides a proven architecture and implementation that helps you to build applications using the common patterns found in line-of-business front-end applications.

  • It allows your application to be based on the concept of modules or plug-ins.
  • Maintainable, reusable code through UI composition.
  • It facilitates development using patterns for loose coupling between modules.
  • Separation of Model (business logic and data access) from Presentation.
  • The Model-View-Presenter pattern.
AlejandroR