Jumping Jack
Jumping Jack

Reputation: 33

Acces dynamically created controls from other method C#

I'm trying to acces my dynamically created Textbox through the click of a button.

private void assortiment_Load(object sender, EventArgs e)
{
    string lastorder = "Select MAX(idorders) From orders";


    string query = "Select * From Product";
    var cmd = new MySqlCommand(lastorder, connection);
    cmd.CommandType = CommandType.Text;
    int orderid = Convert.ToInt32(cmd.ExecuteScalar());
    label1lblorderid.Text = orderid.ToString();
    var cmd2 = new MySqlCommand(query, connection);
    var da = new MySqlDataAdapter(cmd2);
    var ds = new DataSet();
    da.Fill(ds, "Image");
    int count = ds.Tables["Image"].Rows.Count;
    var y = 3;

    for (int i = 0; i < count; i++)
    {
        var data = (Byte[])(ds.Tables["Image"].Rows[i]["Image"]);
        var stream = new MemoryStream(data);

        //picture box creation
        var pbList = new PictureBox
        {
            Name = "pic" + i,
            Size = new Size(150, 150),
            SizeMode = PictureBoxSizeMode.StretchImage,
            Image = Image.FromStream(stream)
        };

        //panel creation
        var tblPanelList = new TableLayoutPanel
        {
            Name = "tblp" + i,
            Size = new Size(380, 150),
            Location = new System.Drawing.Point(219, y),
            BackColor = Color.ForestGreen,
            GrowStyle = TableLayoutPanelGrowStyle.AddColumns,
            ColumnCount = 2
        };

        //other
        productid = Convert.ToInt32((ds.Tables["Image"]
                               .Rows[i]["idproduct"]).ToString());

        //Textbox: Aantal
        var tbAantal = new TextBox { Size = new Size(107, 20), 
                                         Name = "tbaantal" + productid};

        //label productid
        var lblproductid = new Label();
        lblproductid.Text = productid.ToString();

        //Button: Bestellen
        var btnBestel = new Button();
        btnBestel.Name = "bestel" + productid;
        btnBestel.Text = "Bestellen";
        btnBestel.Anchor = AnchorStyles.Right;
        btnBestel.Click += btnBestel_Click;

        //Voeg controls toe
        this.panel.Controls.Add(pbList);
        this.Controls.Add(tblPanelList);
        tblPanelList.Controls.Add(naam);
        tblPanelList.Controls.Add(omschrijving);
        tblPanelList.Controls.Add(lblAantal);
        tblPanelList.Controls.Add(tbAantal);
        tblPanelList.Controls.Add(btnBestel,1,10);
        tblPanelList.Controls.Add(lblproductid);
        y = y + 156;
    }        
}

void btnBestel_Click(object sender, EventArgs e)
{
    MainForm frm_1 = new MainForm();

    var button = sender as Button;
    string btnname = button.Name.ToString();
    //btnname.Remove(1, 6);
    int orderid = Convert.ToInt32(label1lblorderid.Text);
    Control tbAantalControl = FindControl("tbAantal" + btnname.Remove(0, 6));
    int aantal = Convert.ToInt32(tbAantalControl.Text);
    //MessageBox.Show(btnname.Remove(0,6));
    string query = "Insert Into orderproduct(idorder, idproduct, aantal) 
                     Values('" + orderid + "'" + productid +
                     "'" + aantal + "')";
    var cmd = new MySqlCommand(query, connection);
    cmd.ExecuteNonQuery();
}

As you can see, I have already tried to access the Textbox by a FindControl(), But this didn't work. I want the Textbox that has the same last value as the clicked TextBox, I'm trying to do this by cutting the string and paste that in a variable.

Please help.

Upvotes: 0

Views: 700

Answers (3)

Hassan
Hassan

Reputation: 5430

I am not sure you are giving valid control name for search. For checking you should apply break point on the line, to see if you are getting valid control name.

For searching your required control by name you should look into each parent control recursively. FindControl method can be used for the purpose.

Change this:

Control tbAantalControl = FindControl("tbAantal" + btnname.Remove(0, 6));

With this:

Control tbAantalControl = FindControl(this.Controls, "tbAantal" + btnname.Remove(0, 6));

Method that recursive find your required:

 private Control FindControl(Control.ControlCollection controlCollection, string name)
    {
        foreach (Control control in controlCollection)
        {
            if (control.Name.ToLower() == name.ToLower())
            {
                return control;
            }

            if (control.Controls.Count > 0)
            {
                Control result = FindControl(control.Controls, name);
                if (result != null)
                {
                    return result;
                }
            }
        }

        return null;
    }

Upvotes: 1

olydis
olydis

Reputation: 3320

First of all you are searching for TextBoxes with different names than you create them with (tbAantal... vs. tbaantal...). Together with a recursive Find method that would work.

Neither is that good practice nor is it fast.


Better

Rather than searching for controls by name each time you create them you should implement something that directly let's you retrieve the controls (via some identifier or similar, in your case: via productid).

For example:

Declare a Dictionary<int, TextBox> textBoxes as a local variable. In your loop, add textBoxes.Add(productid, tbAantal); right after your definition of tbAantal.

In btnBestel_Click you can then use this mapping to retrieve the correct TextBox via textBoxes[productid]. I am aware that you don't really have the productid defined in that context.

Instead of using btnname.Remove(0, 6), you should use the Buttons's Tag property and store the productid as extra metadata:

Back in your loop add btnBestel.Tag = productid; at the appropriate position. In btnBestel_Click you can then write textBoxes[(int)button.Tag].

Overall code in that case

Dictionary<int, TextBox> textBoxes = new Dictionary<int,TextBox>();

private void assortiment_Load(object sender, EventArgs e)
{
    string lastorder = "Select MAX(idorders) From orders";


    string query = "Select * From Product";
    var cmd = new MySqlCommand(lastorder, connection);
    cmd.CommandType = CommandType.Text;
    int orderid = Convert.ToInt32(cmd.ExecuteScalar());
    label1lblorderid.Text = orderid.ToString();
    var cmd2 = new MySqlCommand(query, connection);
    var da = new MySqlDataAdapter(cmd2);
    var ds = new DataSet();
    da.Fill(ds, "Image");
    int count = ds.Tables["Image"].Rows.Count;
    var y = 3;

    for (int i = 0; i < count; i++)
    {
        var data = (Byte[])(ds.Tables["Image"].Rows[i]["Image"]);
        var stream = new MemoryStream(data);

        //picture box creation
        var pbList = new PictureBox
        {
            Name = "pic" + i,
            Size = new Size(150, 150),
            SizeMode = PictureBoxSizeMode.StretchImage,
            Image = Image.FromStream(stream)
        };

        //panel creation
        var tblPanelList = new TableLayoutPanel
        {
            Name = "tblp" + i,
            Size = new Size(380, 150),
            Location = new System.Drawing.Point(219, y),
            BackColor = Color.ForestGreen,
            GrowStyle = TableLayoutPanelGrowStyle.AddColumns,
            ColumnCount = 2
        };

        //other
        productid = Convert.ToInt32((ds.Tables["Image"]
                                .Rows[i]["idproduct"]).ToString());

        //Textbox: Aantal
        var tbAantal = new TextBox { Size = new Size(107, 20), 
                                            Name = "tbaantal" + productid};
        textBoxes.Add(productid, tbAantal);

        //label productid
        var lblproductid = new Label();
        lblproductid.Text = productid.ToString();

        //Button: Bestellen
        var btnBestel = new Button();
        btnBestel.Name = "bestel" + productid;
        btnBestel.Text = "Bestellen";
        btnBestel.Anchor = AnchorStyles.Right;
        btnBestel.Click += btnBestel_Click;
        btnBestel.Tag = productid;

        //Voeg controls toe
        this.panel.Controls.Add(pbList);
        this.Controls.Add(tblPanelList);
        tblPanelList.Controls.Add(naam);
        tblPanelList.Controls.Add(omschrijving);
        tblPanelList.Controls.Add(lblAantal);
        tblPanelList.Controls.Add(tbAantal);
        tblPanelList.Controls.Add(btnBestel,1,10);
        tblPanelList.Controls.Add(lblproductid);
        y = y + 156;
    }        
}

void btnBestel_Click(object sender, EventArgs e)
{
    MainForm frm_1 = new MainForm();

    var button = sender as Button;
    int orderid = Convert.ToInt32(label1lblorderid.Text);
    Control tbAantalControl = textBoxes[(int)button.Tag];
    int aantal = Convert.ToInt32(tbAantalControl.Text);
    string query = "Insert Into orderproduct(idorder, idproduct, aantal) 
                        Values('" + orderid + "'" + productid +
                        "'" + aantal + "')";
    var cmd = new MySqlCommand(query, connection);
    cmd.ExecuteNonQuery();
}

Upvotes: 2

Slade
Slade

Reputation: 2453

Is there any reason why you can't just make tbAantal a form level variable and then reference that in the btnBestel_Click method?

var tbAantal = null;

private void assortiment_Load(object sender, EventArgs e)
    {
        string lastorder = "Select MAX(idorders) From orders";


        string query = "Select * From Product";
        var cmd = new MySqlCommand(lastorder, connection);
        cmd.CommandType = CommandType.Text;
        int orderid = Convert.ToInt32(cmd.ExecuteScalar());
        label1lblorderid.Text = orderid.ToString();
        var cmd2 = new MySqlCommand(query, connection);
        var da = new MySqlDataAdapter(cmd2);
        var ds = new DataSet();
        da.Fill(ds, "Image");
        int count = ds.Tables["Image"].Rows.Count;
        var y = 3;

        for (int i = 0; i < count; i++)
        {
            var data = (Byte[])(ds.Tables["Image"].Rows[i]["Image"]);
            var stream = new MemoryStream(data);

            //picture box creation
            var pbList = new PictureBox
            {
                Name = "pic" + i,
                Size = new Size(150, 150),
                SizeMode = PictureBoxSizeMode.StretchImage,
                Image = Image.FromStream(stream)
            };

            //panel creation
            var tblPanelList = new TableLayoutPanel
            {
                Name = "tblp" + i,
                Size = new Size(380, 150),
                Location = new System.Drawing.Point(219, y),
                BackColor = Color.ForestGreen,
                GrowStyle = TableLayoutPanelGrowStyle.AddColumns,
                ColumnCount = 2

            };

            //other
            productid = Convert.ToInt32((ds.Tables["Image"].Rows[i]["idproduct"]).ToString());

            //Textbox: Aantal
            tbAantal = new TextBox { Size = new Size(107, 20), Name = "tbaantal" + productid};


            //label productid
            var lblproductid = new Label();
             lblproductid.Text = productid.ToString();


             //Button: Bestellen
             var btnBestel = new Button();
             btnBestel.Name = "bestel" + productid;
             btnBestel.Text = "Bestellen";
             btnBestel.Anchor = AnchorStyles.Right;
             btnBestel.Click += btnBestel_Click;

            //Voeg controls toe
            this.panel.Controls.Add(pbList);
            this.Controls.Add(tblPanelList);
            tblPanelList.Controls.Add(naam);
            tblPanelList.Controls.Add(omschrijving);
            tblPanelList.Controls.Add(lblAantal);
            tblPanelList.Controls.Add(tbAantal);
            tblPanelList.Controls.Add(btnBestel,1,10);
            tblPanelList.Controls.Add(lblproductid);


            y = y + 156;
        }

    }

    void btnBestel_Click(object sender, EventArgs e)
    {
        MainForm frm_1 = new MainForm();

        var button = sender as Button;
        string btnname = button.Name.ToString();
        //btnname.Remove(1, 6);
        int orderid = Convert.ToInt32(label1lblorderid.Text);
        int aantal = Convert.ToInt32(tbAantal.Text);
        //MessageBox.Show(btnname.Remove(0,6));
        string query = "Insert Into orderproduct(idorder, idproduct, aantal) Values('" + orderid + "'" + productid +
                       "'" + aantal + "')";
        var cmd = new MySqlCommand(query, connection);
        cmd.ExecuteNonQuery();
    }

Upvotes: -1

Related Questions