I am using C# 2005 to create a Windows application. I have a MDIForm (frmMainMenu) which contains a Menustrip and a

TabControl. My ChildForm is frmPurchaseEntry. When the user clicks on a particular Menu option a new TabPage is created and

the child form is displayed within the TabPage.

I am using the following code in the MenuClick event of the MDIForm (frmMainMenu) :

frmPurchaseEntry PurchaseEntry = new frmPurchaseEntry();
PurchaseEntry.MdiParent = this;
PurchaseEntry.TabCtrl = tabControl1;
PurchaseEntry.TopLevel = false;
PurchaseEntry.Visible = true;
PurchaseEntry.FormBorderStyle = FormBorderStyle.None;
PurchaseEntry.Dock = DockStyle.Fill;

TabPage tpPurchaseEntry = new TabPage();
tpPurchaseEntry.Parent = tabControl1;
tpPurchaseEntry.Text = PurchaseEntry.Text;
tpPurchaseEntry.Controls.Add(PurchaseEntry);

tpPurchaseEntry.Show();
PurchaseEntry.Select();

tabControl1.SelectedTab = tpPurchaseEntry ;

Everything is OK upto this. But I am unable to remove the TabPage when the ChildForm is closed. The following command only

closes the ChildForm, but the empty TabPage still remains.

this.Close();

I know the syntax to remove a TabPage is

tabControl1.TabPages.Remove(tabControl1.SelectedTab);

But Im unable to access the TabControl of MDIForm from the ChildForm. I tried to use Public modifier for the TabControl, but still it is not exposed from the ChildForm.

How can I remove AND dispose a particular TabPage (with a particular Tab Text) from the ChildForm???

Thank you.

Lalit Kumar Barik

Add a public method on the child form:

public void RemoveActiveTabPage()
{
  tabControl1.TabPages.Remove(tabControl1.SelectedTab);
}

You should not expose controls on the form publically -- you should instead use public methods implementing the functionality you intend to call from other classes

Add a public method on the child form:

public void RemoveActiveTabPage()
{
  tabControl1.TabPages.Remove(tabControl1.SelectedTab);
}

You should not expose controls on the form publically -- you should instead use public methods implementing the functionality you intend to call from other classes

Sorry to bother you again sknake. But I am rather new to C# 2005 (having migrated from VB 6 rather late) and not too bright either. I am slow to understand new things.

As I mentioned in my original post, the TabContainer is placed in the MDIForm and I am trying to remove a TabPage from my ChildForm. Therefore should I place the Public method suggested by you in the MDIForm or the ChildForm?

Also, if I place the Public Method in the MDIForm, how do I call it from the ChildForm??? The syntax please.

Thanks again.

Lalit Kumar Barik

Are you using VS 2005 or 2008? I will upload a sample project if you're running 2008 -- if not I will paste code.

I am using VS 2005 for the particular application but thinking of migrating to VS 2008.

Pasting a code will do for now.

Lalit Kumar Barik

Master:

using System.Windows.Forms;

namespace daniweb
{
  public partial class frmMaster : Form
  {
    private frmChild _child;

    public frmMaster()
    {
      InitializeComponent();
    }
    private void OpenChildForm()
    {
      _child = new frmChild();
    }
    private void RemoveChildTab()
    {
      _child.RemoveTabPage();
    }
  }
}

Child:

using System.Windows.Forms;

namespace daniweb
{
  public partial class frmChild : Form
  {
    public frmChild()
    {
      InitializeComponent();
    }
    public void RemoveTabPage()
    {
      //tabPage.Remove();
    }
  }
}

VS2008 eats 2005 projects for difference so I will post the code changes :)

Can you indicate how I should use your application and the unwanted behavior so I know where to look? Thanks

@sknake, Thanks for your offer to help.

As mentioned earlier, I am using C# 2005.

In the User Interface, I am trying to implement the following.

The MDIForm should display a Menu Strip and a Status Bar (not yet done in the current coding). Since I had faced some problems in displaying multiple child forms at the same time in an MDIForm (the forms used to cascade if I display a new child form without closing the earlier child form) in the past, I thought of displaying the child forms inside tab pages. That way, I can display different child forms inside Tab Pages and the user could select any option from the menu to display a child form. I am NOT implementing the File -> New feature of other Windows programs like MS Word. Rather each menu option represents a distinct child form. If the user chooses the same menu option again, then the previously created child form should be displayed (retaining the already entered values to text boxes, combo boxes, etc. The user could also click on the Tab name to bring the corresponding child form to front and work.

Till now, I am experimenting with displaying a single child form only (Purchase Entry). I have been successful in adding new Tab pages as required and display the child form in it. Also only a single instance of a particular child form/Tabpage is being created (for the Purchase Entry option only till now).

My first problem is in removing and disposing the form and tab when the user closes the child form.

Also I would like to add individual close buttons (X) to each TabPage (like Tab pages in Opera browser).

Alternately, I would like to display a single "X" at the extreme right, clicking on which should close the currently selected TabPage (like the Tabbed document feature of VS 2005).

I want to get rid of the ugly grey bar at the top of the form (or atleast display a panel or something) which appears when a Tabpage is created. Or I can change the backcolor of the MDIForm to something else. (I am NOT sure about this until I see it in action).

That is all for the time being.

Thanks again for your suggestions.

Lalit Kumar Barik

On your child form:

private void btnClose_Click(object sender, EventArgs e)
        {
          tabCtrl.TabPages.Remove(tabPag);
          tabPag.Dispose();
          this.Close();
          this.Dispose();
        }

On your master form (I added one line -- look for the comment):

private void purchaseEntryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            bool blnFormCreated = false;
            int intTabId;
            foreach (TabPage tpTest in tabControl1.TabPages)
            {
                if (tpTest.Text == "Purchase Entry")
                {
                    blnFormCreated = true;
                    intTabId = tabControl1.TabIndex;
                }
            }

            if (!blnFormCreated)
            {
                frmPurchaseEntry PurchaseEntry = new frmPurchaseEntry();
                PurchaseEntry.MdiParent = this;
                PurchaseEntry.TabCtrl = tabControl1;
                PurchaseEntry.TopLevel = false;
                PurchaseEntry.Visible = true;
                PurchaseEntry.FormBorderStyle = FormBorderStyle.None;
                PurchaseEntry.Dock = DockStyle.Fill;

                TabPage tpPurchaseEntry = new TabPage();
                tpPurchaseEntry.Parent = tabControl1;
                tpPurchaseEntry.Text = PurchaseEntry.Text;
                tpPurchaseEntry.Controls.Add(PurchaseEntry);

              //you were missing this line
                PurchaseEntry.TabPag = tpPurchaseEntry;

                tpPurchaseEntry.Show();
                PurchaseEntry.Select();
            }

            SetDefaultTab("Purchase Entry");
        }
Comments
You solved my problem.

@sknake, Thanks for your solution (post #10). It worked beautifully. Now I am ready to face other challenges and would try to implement other features I mentioned.

This forum is really great.

My hearty thanks .

Lalit Kumar Barik

You're welcome and good luck! I didn't delve in to the other questions because they weren't the original topic for the thread but if you can't find a solution go ahead and open up a new thread and someone will get back to you.

This question has already been answered. Start a new discussion instead.