Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 514
  • Last Modified:

GUI design with many panels: Best Practice?

Dear Experts,

right now I am designing a small ERP application (C#.net, Visual Studio 2005). Although it is rather small in ERP terms, it is nevertheless rather complex in absolut terms. The GUI consists of a couple of navigation areas (panels), which should stay constant during the entire usage, and a main content area which varies a lot.

Up to now, I am using a different panel for each type of content area (there are about 30 of those). All of these panels reside in the same form with same position and size, but only the active one is visible. However, this approach has two severe drawbacks:
1) Using these panels in the Visual Studio Designer is a pain in the ass. Since all content panels completely overlap and only the most recent is visible, it is akward to target a specific control on a specific panel. I have to move all but one panels to a far off location, edit one panel, move this panel away and get another one, and so forth.
2) The application loads and virtually draws all panels at startup. Well, actually I don't know if they get drawn as they are invisible, but startup time significantly slows down the more panels I have in the form. This wouldn't be necessary because most use cases touch only a couple of the content panels. I would appreciate an approach that loads and draws the panels at runtime. I know I can do that programmatically, but then I couldn't use the Visual Studio Designer any more, could I?

Does anyone know a Best Practice for designing complex GUIs with many panels in Visual Studio? Is my approach sensible, has any one figured out a better way to do it? Should I give up using the Visual Studio Designer for the content panels and build the GUI by pure code?
All comments or ideas are most welcome.

Thanks in advance,
woolf
0
wlfs
Asked:
wlfs
  • 4
  • 2
  • 2
  • +2
3 Solutions
 
wlfsAuthor Commented:
Supplemental comment:

What I am desperately hoping for, is a functionality like subforms in MS Access. There, I can design as many subforms as I like completely independently from each other. In the main form, I have only a single subform control whose SourceObject property can be bound at runtime. This counters both drawbacks that I described in my question:
1) Independet design phase of the subforms.
2) Dynamic loading and binding of subforms during runtime as needed.

Is there a way to mimic this functionality in C# Visual Studio 2005?
0
 
Ready1Commented:
You can use various controls such as docking tools: http://www.codeproject.com/cs/miscctrl/docking_control.asp

You may be able to utilise a tab control that has the tabs hidden thus displaying only certain data on a tab. You can also organise your 30 panels a lot easier. If you wanted to be adventurous is to programatically rearrange panels during runtime so panels that you want to appear will be placed on the selected tab...

Regards,
Ready1
0
 
topdog770Commented:
One approach is to create the panels as user controls, you can then add or display the panels as needed AND still use the IDE to design and work on each panel separately.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
gbzhhuCommented:
I agree with topdog770 100% from experience.  I have this app that is wizard like with many panels (originally)  I run into the same problems as you.  The designer issue really did wind me up.  I created a user control for each panel (really easy to concentrate 1 user control at a time) then in my main form I have 1 main panel (for contents)  When the form loads I add the initial user control to the panel and show it.  Depending on users action I add the right user control to the panel
0
 
wlfsAuthor Commented:
Hi Experts,

thanks a lot for your responses, which were very valuable to me.

A tab control with hidden tabs seems to be the direct answer to my initial question. I actually didn't know you can hide the tabs. And I was amazed how many commercial Visual Studio controls are out there when you google for "docking tools". Thanks Ready1.

However, the idea of making each panel a user control of its own really appeals to me. This does not only solve my initial problem, but it also provides a perfect place for encapsulating the panel-specific parts of the business logic. The more I think about it, the more I like it. I am now actually looking forward to implementing it. Thanks guys for putting some fun back into my project :)

woolf
0
 
topdog770Commented:
You're welcome!
0
 
pgloorCommented:
Even I would not yet call myself an Expert in this field I agree with topdog770 and gbzhhu. Basically I'm doing the same.

In the simple version I simply declare my controls near the top of my forms code, where I also have a currentControl of type UserControl. I always set currentControl to the currently active (visible) user control.

private UserControl1 userControl1 = null;
private UserControl2 userControl2 = null;
private UserControl currentControl = null;

When I'm using the control for the first time I'm checking whether it has been initialized before or not. If not, I create a new user control and call a method that initializes the new user control and displays it in the panel. Otherwise I call another method that simply hides the currentControl, displays the given user control in the panel and makes it the new currentControl.

if (this.userControl1 == null) {
  this.userControl1 = new ExpertOne.UserControl1();
  // Initialize and show user control
  ShowUserControl(this.userControl1, "userControl1");
} else {
  // Just show the already initialized user control
  ShowUserControl(this.userControl1);
}


My methods look something like this:

private void ShowUserControl(UserControl uc, string ucName) {
  panel2.SuspendLayout();
  this.panel2.Controls.Add(uc);
  uc.Name = ucName;
  uc.Dock = System.Windows.Forms.DockStyle.Fill;
  uc.Location = new System.Drawing.Point(0, 0);
  uc.Size = this.panel2.Size;
  uc.TabIndex = 0;
  uc.Visible = true;
  if (currentControl != null) {
    if (currentControl.GetType() != uc.GetType()) {
      currentControl.Visible = false;
    }
  }
  currentControl = uc;
  panel2.ResumeLayout();
}

private void ShowUserControl(UserControl uc) {
  panel2.SuspendLayout();
  uc.Visible = true;
  if (currentControl != null) {
    if (currentControl.GetType() != uc.GetType()) {
      currentControl.Visible = false;
    }
  }
  currentControl = uc;
  panel2.ResumeLayout();
}

Doing so guarantees that my code is never loaded more than once and is kept in memory for reuse if needed.

However, large user controls or controls loading data are sometimes loading slow if they are loaded for the first time. The more complicated way is to load the user controls into a collection when they will be used but also to preload the critical and slowly loading components in advance (e.g. in a backworker process).

Peter
N.B. Above code is far from being perfect. It just there to provide an idea.
0
 
wlfsAuthor Commented:
Hello Peter,

thanks a lot for sharing the code snippets and your expertise. I really appreciate your help.
I am sorry that we were cross-posting and I had the points assigned before receiving your post.

regards, woolf.
0
 
gbzhhuCommented:
pgloor

It is quite funny and perfect coincidence.  I am using CurrentControl (as a property ) in my project.  The only difference to yours is that I have an array of user controls

wlfs,
I have this suggestion that made my life a lot easier.  Create an interface and put there all the properties and methods that all your user controls need then all your user controls implement this interface.  For example in my scenario I have the following

1.  IsDirty   - a property that is set to true if changes are made to the controls on the usercontrol
3.  PopulateControls()   -  a method that populates the controls on the first load of the usercontrol
4.  RefreshControls()    -   a method that when a control changes refreshes other controls that depend on the value of the changed control

I have taken some more that I feel are too specific for my project

#region Interfaces
/// <summary>
/// Interface implemented by all the user controls that go into the wizard
/// </summary>
public interface IWizardControl
{
      bool IsDirty { get; set; }

      void PopulateControls();
      void RefreshControls();
}
#endregion


0
 
wlfsAuthor Commented:
Great suggestion, gbzhhu. As I wrote before, apart from solving the design problems your approach leads to a cleaner overall structure of the code as well. Very appealing. And I am wondering quite much now, why I didn't have the idea myself :)
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 4
  • 2
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now