简体   繁体   中英

make a tab from a user control

I'm having problems. I get a lot of errors and this is annoying me when I'm trying to add tabs from a user control. Here is the code

public Form1 f1 { get; private set; }

private void button1_Click(object sender, EventArgs e)
{
    TabPage tp = new TabPage { };
    tp.Text = "NewTab";
    tp.Controls.Add(new b());
    f1.tabControl1.TabPages.Add(tp);  //>>> errors here
}

Image for more details: code no showing errors

Run-time errors

Your code isn't assigning f1 which is why you are getting a null reference exception at run time.

Depending on the architecture of your project ...

A. If UserControl is instantiated in the parent Form code behind then simply inject f1 into the constructor of the UserControl :

private readonly MyForm _f1;

public b(MyForm f1){
    InitializeComponents();

    _f1 = f1;
}

private void button1_Click(object sender, EventArgs e) {
    TabPage tp = new TabPage { };
    tp.Text = "NewTab";
    tp.Controls.Add(new b());

    //  assumes 'tabControl1' exists as a publicly accessible control
    _f1.tabControl1.TabPages.Add(tp);
}

B. If using MVP then, using the code you have, the Presenter can assign the f1 variable at initialization but make the setter public or internal .

f1 is null because no form has been assigned to it. Drop this property and instead write:

TabPage tp = new TabPage { };
tp.Text = "NewTab";
tp.Controls.Add(new b());
FindForm().Controls.OfType<TabControl>().Single().TabPages.Add(tp);

This assumes that the form contains exactly one TabControl and that it is a top level control. If it can be inside another container control, you will have to loop the controls recursively. This question might help: Loop through all controls on a form, even those in groupboxes

Note, that your approach has yet another issue: f1 is typed as Form , but this general type has no tabControl1 . You would have to type it with a specific form type MyForm f { get; set; } MyForm f { get; set; } MyForm f { get; set; } .


Maybe an easier way to access the TabControl is to let the form implement an interface defining just a property returning this TabControl:

public interface ITabControlProvider
{
    TabControl MainTabControl { get; }
}

Then let your form implement it

public partial class MyForm : Form, ITabControlProvider
{
    ...

    TabControl MainTabControl { get { return tabControl1; } }
}

Now your UserControl can find the TabControl like this

var frm = FindForm() as ITabControlProvider;
if (frm != null) {
    frm.MainTabControl.TabPages.Add(tp);
}

As this code looks like it is all happening from inside a form, you can try this :

public Form1 f1 { get; private set; }

private void button1_Click(object sender, EventArgs e)
{
    if(f1 == null) { f1 = this; }
    TabPage tp = new TabPage { };
    tp.Text = "NewTab";
    tp.Controls.Add(new b());
    f1.tabControl1.TabPages.Add(tp);  //>>> errors here
}

If it is happening inside a UserControl , then you can try this :

public Foo : UserControl {

    public TabControl tabControl { get; set; }

    private void button1_Click(object sender, EventArgs e)
    {
        if(tabControl == null) {
            // do nothing - ignore button click.
        } else {
            TabPage tp = new TabPage { };
            tp.Text = "NewTab";
            tp.Controls.Add(new b());
            tabControl.TabPages.Add(tp);  //>>> errors here
        }
    }
}

The on the form you have this user control added to, you can either choose the TabControl it is bound to from the drop-down menu in the property editor, or you can assign it in code like this :

foo1.tabControl = tabControl1;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM