Must I remove a form assigned to a TabPage and then add a new one, or can I access the existing one to change values it contains dynamically?

StackOverflow https://stackoverflow.com/questions/9832655

Question

I am dynamically assigning forms to tab pages. It works fine, except when I try to assign an updated version of the form (with different text values assigned to the controls) to the tab page. I am actually a little surprised that it doesn't crash when I create multiple instances of the form and assign them to the tab page (if the new ones are just stacking on top of the older ones, you would think the new one would be on top and the new values are visible).

So...what do I need to do to remove the previous form I added to the tab page before adding the new version? Or can I access the existing form and change its values.

I guess it would be clearer if I just showed the code:

Main form:

    private enum TabControls {
        BasicInfo,
        ConfidentialInfo,
        RolesAndSecurity,
        InactiveInfo
    }

    string currentNode = string.Empty;

    public Form1() {
        InitializeComponent();
        CenterToScreen();
    }

    private void treeView1_AfterSelect(object sender, TreeViewEventArgs e) {
        currentNode = e.Node.Name;
        UpdateActiveTabForNode();
    }

    // This is called both by treeView1_AfterSelect (sic, I changed the name to 
    // treeViewSearchWorker) and by tabControlWorker_SelectedIndexChanged(). 
    // currentNode is set/overwritten on clicking a node and saved in a form var.
    // The active tab page is always known via the TabControl's SelectedIndex
    // property, so there is no need to pass in either value.
    private void UpdateActiveTabForNode() {
        int ActiveTabPage = tabControlWorker.SelectedIndex;

        switch (ActiveTabPage) {
            case (int)TabControls.BasicInfo:
                if (tabPageBasicInfo.Controls.Count > 0) {
                    ;// tabPageBasicInfo.Controls.Remove(0);<-- What to pass in here?
                }
                    BasicInfoPseudoTab bipt = new BasicInfoPseudoTab(currentNode);
                    tabPageBasicInfo.Controls.Add(bipt);
                tabPageBasicInfo.BringToFront();
                    bipt.Show();
                break;
            case (int)TabControls.ConfidentialInfo:
                ConfidentialInfoPseudoTab cipt = new ConfidentialInfoPseudoTab(currentNode);
                tabPageConfidentialInfo.Controls.Add(cipt);
                cipt.Show();
                break;
            case (int)TabControls.RolesAndSecurity:
                RolesAndSecurityPseudotab raspt = new RolesAndSecurityPseudotab(currentNode);
                    tabPageRolesAndSecurity.Controls.Add(raspt);
                    raspt.Show();
                break;
            case (int)TabControls.InactiveInfo:
                InactiveInformationPseudoTab iipt = new InactiveInformationPseudoTab(currentNode);
                    tabPageInactiveInfo.Controls.Add(iipt);
                    iipt.Show();
                break;
            default: {
                    break;
                    // TODO: Do something?
                }
        }
    }

    private void tabControlWorker_SelectedIndexChanged(object sender, System.EventArgs e) {
        UpdateActiveTabForNode();
    }
}

==== Form that serves as one of the pseudo tabPages:

public partial class BasicInfoPseudoTab : Form {
    String _aNodeName = String.Empty;

    public BasicInfoPseudoTab(String ANodeName) {
        InitializeComponent();
        // Without this, you get "TopLevel control cannot be added to a control"
        this.TopLevel = false;
        this.FormBorderStyle = FormBorderStyle.None;
        this.Visible = true;
        this.Dock = DockStyle.Fill;
        _aNodeName = ANodeName;
        SetDisplayVals();
    }

    private void SetDisplayVals() {
        if (_aNodeName == "NodeBuckingham") {
            textBoxFirstName.Text = "Buckingham";
            textBoxLastName.Text = "Piranha";
            textBoxNickname.Text = "B.P.";
        }
        else if (_aNodeName == "NodeVolcano") {
            textBoxFirstName.Text = "Volcano";
            textBoxLastName.Text = "Jerry";
            textBoxNickname.Text = "V.J.";
        } else if (_aNodeName == "NodeParsons") {
            textBoxFirstName.Text = "Parsons";
            textBoxLastName.Text = "Spalding";
            textBoxNickname.Text = "P.S.";
        } else {
            textBoxFirstName.Text = String.Empty;
            textBoxLastName.Text = String.Empty;
            textBoxNickname.Text = String.Empty;
        }
    }

Updated:

I got it working by declaring the form variables outside the event handler and disposing them if they were not null before proceeding.

    string currentNode = string.Empty;
    BasicInfoPseudoTab bipt;
    ConfidentialInfoPseudoTab cipt;
    RolesAndSecurityPseudotab raspt;
    InactiveInformationPseudoTab iipt;

    . . .

    private void treeView1_AfterSelect(object sender, TreeViewEventArgs e) {
        currentNode = e.Node.Name;
        UpdateActiveTabForNode();
    }

    private void UpdateActiveTabForNode() {
        int ActiveTabPage = tabControlWorker.SelectedIndex;

        switch (ActiveTabPage) {
            case (int)TabControls.BasicInfo:
                if (null != bipt) {
                    bipt.Dispose();
                }
                bipt = new BasicInfoPseudoTab(currentNode);
                tabPageBasicInfo.Controls.Add(bipt);
                bipt.Show();
                break;
            . . .
Was it helpful?

Solution

As you wish, use module level variables, one for each form, if null, new it, else as above. If you are creating forms constantly on top of each other how are you ever going to clean up? Check the size of your working set as you keep creating forms.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top