jankes
jankes

Reputation: 27

NullReferenceException dynamically created controls, object seems to exist

In Win Forms I have these three test methods. First to create a button, second to create a tab control with two tabs and third to move created button to first tab.

private void button1_Click(object sender, EventArgs e)
    {
        Button przycisk = new Button();
        przycisk.Location = new Point(24, 250);
        przycisk.Name = "nowy";
        przycisk.Text = "utworzony";
        przycisk.Width = 131;
        przycisk.Height = 23;
        Controls.Add(przycisk);
    }

    private void button2_Click(object sender, EventArgs e)
    {
        TabControl zakladki = new TabControl();
        zakladki.Location = new Point(208, 160);
        zakladki.Name = "zakl";
        zakladki.Height = 150;
        zakladki.Width = 208;
        zakladki.TabPages.Add("zakladka1", "pierwsza");
        zakladki.TabPages.Add("zakladka2", "druga");
        Controls.Add(zakladki);
    }

    private void button3_Click(object sender, EventArgs e)
    {
        TabControl zakladki = (TabControl)Controls.Find("zakl", false).FirstOrDefault();
        int numerZakladki = 1;
        foreach (TabPage zakladka in zakladki.TabPages)
        {
            Control kt = Controls["nowy"];
            kt.Location = new Point(10, 10); // System.NullReferenceException
            zakladka.Controls.Add(kt);
            numerZakladki++;
        }
    }

I'm having a hard time to understand the behavior upon trying to change the referenced button location. The code above throws System.NullReferenceException, but when I do

if (kt != null)
{
    kt.Location = new Point(10, 10);
}

it works as expected. Can anyone explain it to me ?

Upvotes: 0

Views: 479

Answers (3)

g.schroeter
g.schroeter

Reputation: 24

The new TabControl contains two Tabs. If you move the button to the first Tab, the control at the Main form is null. Code without Loop:

    private void button3_Click(object sender, EventArgs e)
    {
        TabControl zakladki = (TabControl)Controls.Find("zakl", false).FirstOrDefault();
        Control kt = Controls["nowy"];
        kt.Location = new Point(10, 10);
        zakladki.TabPages[0].Controls.Add(kt);
    }

Upvotes: 1

vgru
vgru

Reputation: 51224

You move the "nowy" button from the Form.Controls to the first TabPage's Controls collection. This removes the control from the first collection, so the code throws the exception on the next iteration. A Control can have only a singleParent.

Either create the Button for each tab separately (instead of moving it), or add the Button to the first tab only (without the foreach loop).

Upvotes: 0

Patrick Hofman
Patrick Hofman

Reputation: 156978

Your nowy controls are added to the root control (Form I guess), but you are trying to find them in the tab pages under zakl. You have to either add the controls to the tab page, or find them in the root control, just like you did with zakl.

Upvotes: 0

Related Questions