2

I have a form which has three tabs. Now each of the tab has some 15 - 20 functions. So when combined, I have around 50 methods and it becomes quite cumbersome to handle such a big class. Are there any better ways of handling such a large file. Do these methods help: 1) three partial classes 2) seperate classes(non partial) for each tab 3) regions

Please share your experiences. Thanks in Advance!

tarun_tenniso
  • 214
  • 5
  • 20

5 Answers5

4

You could separate each of the tabs into separate user controls. Or even go for a more granular level than that.

gmn
  • 4,199
  • 4
  • 24
  • 46
  • Not much knowledge about user controls. Are there any links for tutorials and understanding? – tarun_tenniso Feb 19 '14 at 08:46
  • @tarun_tenniso http://msdn.microsoft.com/en-us/library/aa302342.aspx although a quick google for Winforms user controls will come up with lots of examples. – gmn Feb 19 '14 at 08:49
4

For each TabPageof your TabControl do the following:

Drag a Panel from the toolbar into the TabPage. Set the Dock property of the panel to Fill.

In the Solution Explorer, create a new element of type Windows Forms.

Set FormBorderStyle in your new form to None

Use the following code in the form containing the TabControl

public MainFrm()
{
    InitializeComponent();

    var subFrm = new SubFrm();
    subFrm.TopLevel = false;
    subFrm.Dock = DockStyle.Fill;
    panelInTabPage.Controls.Add(subFrm);
    subFrm.Show();
}

Now you can store the logic of each subform in its own source file.

2

For static tabs I usually segregate into their own partial class. Any functions which are shared between I try to put in a single separate class and call when needed.

dave88
  • 312
  • 5
  • 14
  • This is a lot cleaner than user controls. Simply move your code (most likely in regions) from the main form into several partial class files in the same namespace, derived from Form. Don't make the sibling files as dependent on the main form for maintenance reasons. Done in 2 minutes... – Brian Leeming Aug 18 '16 at 14:54
1

I have come across this problem before and had the requirement that we use no third party controls so that the application could be easily handed over to a third party. To get around this we had a main form which we set IsMdiContainer = true and dock a TabControl to the to of the main form so that only the TabItems are visible and the contents is not.

Now, this is not the nicest, but it solves the problem and allows you to write the contents of each tab as a seperate form having its own class etc. On the main form set the load event to load the relevant forms into you TabControl.

Note, you can replace the use of Forms in what follows with UserControls but you will use the ability to have the main form as an MdiContainer and will have to use a Panel to dock controls and add some code to bring each user control to front.

private void MainForm_Load(object sender, EventArgs e)
{
    try {
        LoadMdiForms();
    }
    finally {   
        mdiTabControl.SelectedIndex = 0;
    }       
}

Then set up a List<Form> MdiChildForms { get; set; } and add you forms

private void LoadMdiForms()
{
    createDbForm = new CreateDbForm();
    MdiChildForms.Add(createDbForm);
    valForm = new ValidationForm();
    MdiChildForms.Add(valForm);
    // et al.

    foreach (Form mdiChild in MdiChildForms)
    {
        mdiChild.MdiParent = this;
        mdiChild.ShowInTaskbar = false;
        mdiChild.Show();
    }
}

Now set up an MainForm_MdiChildActivate event handler

private void MainForm_MdiChildActivate(object sender, EventArgs e)
{
    if (this.ActiveMdiChild == null)
        mdiTabControl.Visible = false; // If no child forms, hide tabControl
    else
    {
        // Child form always maximized.
        this.ActiveMdiChild.WindowState = FormWindowState.Maximized; 

        // If child form is new and has no tabPage, create new tabPage.
        if (this.ActiveMdiChild.Tag == null)
        {
            // Add a tabPage to tabControl with child form caption
            TabPage tp = new TabPage(this.ActiveMdiChild.Text);
            tp.Tag = this.ActiveMdiChild;
            tp.Parent = mdiTabControl;
            mdiTabControl.SelectedTab = tp;
            this.ActiveMdiChild.Tag = tp;
            this.ActiveMdiChild.FormClosed += new FormClosedEventHandler(ActiveMdiChild_FormClosed);
        }

        // Make visible if required.
        if (!mdiTabControl.Visible) 
            mdiTabControl.Visible = true;
    }
}

Now add the event handler on the TabControl SelectedIndexChanged event

// If child form closed, remove tabPage.
private void ActiveMdiChild_FormClosed(object sender, FormClosedEventArgs e)
{
    ((sender as Form).Tag as TabPage).Dispose();
}

private void mdiTabControl_SelectedIndexChanged(object sender, EventArgs e)
{
    if ((mdiTabControl.SelectedTab != null) && 
         (mdiTabControl.SelectedTab.Tag != null))
    {
        this.BeginUpdate();
        (mdiTabControl.SelectedTab.Tag as Form).Select();
        this.EndUpdate();
    }
}

That's it. You should have a working TabControl with atomic TabItems.

I hope this helps.

MoonKnight
  • 23,214
  • 40
  • 145
  • 277
0

A few approaches handling GUI components:

  • When starting up a new project, we always have some base user control (or at least interface)
  • whenever we feel a particular control (other than standard user control) could be used somewhere else, we separate it out as a custom user control.
  • We normally segregate all custom user controls to a standalone project.

for your particular issue, you could separate each tab as a standalone custom user control.

some work-through: http://msdn.microsoft.com/en-us/library/aa302342.aspx

Rex
  • 2,130
  • 11
  • 12