Reputation: 33
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
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
Reputation: 3320
First of all you are searching for TextBox
es 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
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