0

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

IAbstract
  • 19,551
  • 15
  • 98
  • 146
  • 3
    what errors are you getting? – Raktim Biswas Aug 08 '16 at 19:29
  • Sorry, but we can't read in your mind or direct from your screeen... You have to provide more details about your issues, if you want our help. – Maciej Los Aug 08 '16 at 19:31
  • In your Windows Forms Designer, make `tabControl1` access modifier public in `Form1` It's an option in the property list. – xofz Aug 08 '16 at 19:40
  • Did you set `f1` to the form object ? For example if the above code is inside the class `Foo`, did you call it from within the instance of `Form1` like this `Foo.f1 = this;` or `Foo.f1 = new Form1();`. If you do not tell the program what instance of `Form1` is to be used for `f1` by assigning it, it will give you a null exception since no instance of `Form1` has been assigned to `f1`. – Kraang Prime Aug 08 '16 at 20:16

3 Answers3

6

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 M-V-P then, using the code you have, the Presenter can assign the f1 variable at initialization but make the setter public or internal.

IAbstract
  • 19,551
  • 15
  • 98
  • 146
0

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; }.


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);
}
Community
  • 1
  • 1
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
0

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;
Kraang Prime
  • 9,981
  • 10
  • 58
  • 124