从其他方法C#访问动态创建的控件

时间:2014-06-08 08:47:55

标签: c# winforms

我正试图通过点击按钮来访问我动态创建的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};

        //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();
}

正如您所看到的,我已经尝试通过Textbox访问FindControl(),但这不起作用。我希望Textbox与被点击的TextBox具有相同的最后一个值,我试图通过剪切字符串并将其粘贴到变量中来实现此目的。

请帮忙。

3 个答案:

答案 0 :(得分:2)

首先,您要搜索的TextBox es名称与您创建的名称不同(tbAantal...tbaantal...)。与 工作的递归Find方法一起使用。

既不是好的做法,也不是很快。


<强>更好

不是每次创建控件时都按名称搜索控件,而是应该实现直接让您检索控件的内容(通过某些标识符或类似内容,在您的情况下:via { {1}})。

例如:

productid声明为局部变量。在您的循环中,在定义Dictionary<int, TextBox> textBoxes之后立即添加textBoxes.Add(productid, tbAantal);

tbAantal中,您可以使用此映射通过btnBestel_Click检索正确的TextBox。 我知道你并没有真正在那个环境中定义textBoxes[productid]

您应该使用productid的{​​{1}}属性,而不是使用btnname.Remove(0, 6),并将Buttons存储为额外的元数据:

回到你的循环中,在适当的位置添加Tag。在productid中,您可以撰写btnBestel.Tag = productid;

该案例的整体代码

btnBestel_Click

答案 1 :(得分:1)

我不确定您是否为搜索提供了有效的控制名称。要进行检查,您应该在该行上应用断点,以查看您是否获得了有效的控制名称。

要按名称搜索所需的控件,您应该以递归方式查看每个父控件。 FindControl方法可用于此目的。

改变这个:

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

有了这个:

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

递归查找所需的方法:

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

答案 2 :(得分:-1)

有什么理由不能让tbAantal成为表单级变量,然后在btnBestel_Click方法中引用它?

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();
    }