0

I am trying to run two parallel foreach Loop

Code:

foreach (Control c in panel1.Controls)
{
    if (c.GetType() == typeof(CheckBox))
    {
        if (((CheckBox)c).Checked) 
        {
            id = name; 
        }
    }
}

if (id != "")
{
    foreach (Control cd in panel1.Controls)
    {
        if (cd.GetType() == typeof(TextBox) && cd.Name == name)
        {
            val = cd.Text.ToString();

            if (val != "")
            {
                con3.Open();
                SqlCommand cmd3 = new SqlCommand("insert into Employee_Ear_Ded values('" + Convert.ToInt32(name) + "','" + Convert.ToInt32(comboBox1.Text) + "','" + drpPayHead.Text + "','" + Convert.ToDouble(val) + "','" + comboBox2.Text + "')", con3);
                cmd3.ExecuteNonQuery();
                con3.Close();
            }
            else
            {
                MessageBox.Show("Please Enter Value");
            }
        }
    }
}
else
{
    MessageBox.Show("No Employee Selected");
}

Here I am trying to insert the value of the text box whose respective checkbox is Checked.
The code I am using is inserting only the last value checked.
How can I run it for each checkbox and its respective textbox?
The controls are created at runtime.

Dariusz
  • 21,561
  • 9
  • 74
  • 114
Hanumendra
  • 309
  • 2
  • 9
  • 22
  • Keep a list of checked ids and iterate those? – Carra Jun 05 '13 at 11:10
  • name is name of the checkbox – Hanumendra Jun 05 '13 at 11:12
  • Off topic but I'd recommend doing ITextControl cd as ITextControl, null check and then calling cd.Text. It's likely to be better performance than reflecting every control on the page. – Liath Jun 05 '13 at 11:15
  • 2
    Your code is vulnerable to SQL injection. – Dai Jun 05 '13 at 11:15
  • How are these parallel? – Dan Puzey Jun 05 '13 at 11:29
  • You stated: "... the text box whose respective checkbox is Checked" along with: "The controls are created at runtime." So why not preserve the association when you create those controls? This could be as simple as keeping a reference to the TextBox in the Checkbox.Tag property, or using a Dictionary...then you don't have to go iterating to find a "match". – Idle_Mind Jun 05 '13 at 14:50

4 Answers4

3

You could loop only over the checkboxes using the Enumerable extension OfType and then over the textboxes with the same syntax

foreach (CheckBox c in panel1.Controls.OfType<CheckBox>())
{
    if (c.Checked)
    {
        foreach(TextBox cd in panel1.Controls.OfType<TextBox>())
        {
            string val = cd.Text;
            if (val != "" && cd.Name == name)
            {
              con3.Open();
              SqlCommand cmd3 = new SqlCommand("insert into ....", con3)
              cmd3.ExecuteNonQuery();
              con3.Close();
            }
        }
    }
}

Said that, I really suggest you to look for parameterized queries.
Your database command text built concatenating string values is very dangerous (Sql Injection) and could fail if there are some invalid characters in the input strings

Also, as it stand the code now, the sql command seems wrong.
The code converts the variable name (a string) to an integer and then encloses the result into single quotes.
This is like saying that the database field that receive the name value is of text type and thus the integer conversion was not necessary.

Community
  • 1
  • 1
Steve
  • 213,761
  • 22
  • 232
  • 286
  • thanks for your help but the val is storing cd.Text and cd is specified with the type text and c is checkbox. I am trying to store value of text box whose associated checkbox is checked, cd is not declared here – Hanumendra Jun 05 '13 at 11:19
  • Yes, now I understand better. Updated the answer – Steve Jun 05 '13 at 11:25
  • foreach for the textbox is running under foreach of checkbox. I want to run both the foreach in parallel iterations, i.e together in the same loop and not two different loops. – Hanumendra Jun 05 '13 at 11:27
  • I think it is not possible. If you need to exit immediately after the update you could add the break statement – Steve Jun 05 '13 at 11:35
  • It is giving the same result, it is entering the only last checked value in the database as many times as the number of check boxes selected – Hanumendra Jun 06 '13 at 07:20
  • This is a different problem. The Insert command writes always the same value with the possible exception of the variable `val`. I suggest you to create a new question for this – Steve Jun 06 '13 at 07:46
1

I would iterate inside an iteration.

Loop inside loop.

Another, and perhaps better way is to set the unused property "tag" of checkbox to the corresponding control of the textbox.

Would be very easy to link both objects, and with the right method design You can save both iterations.

icbytes
  • 1,831
  • 1
  • 17
  • 27
0

I don't see how you link checkbox to textbox. The "id=name" inside the upper nested loop makes little sense because it does not involve the loop variables. I assume that you want a list of all "checked" checkboxes. This is one way to achieve it. You can iterate over TextBoxes in the same way to access their contents.

var namesOfCheckedBoxes = panel1.Controls.OfType<CheckBox>().Where(cb=>cb.Checked).Select(cb=>cb.Name);
Tormod
  • 4,551
  • 2
  • 28
  • 50
0

I tried this and it worked

foreach (CheckBox c in panel1.Controls.OfType<CheckBox>())
{
if (c.Checked)
{
    var name = c.Name;
    foreach(TextBox cd in panel1.Controls.OfType<TextBox>())
    {
        string val = cd.Text;
        if (val != "" && cd.Name == name)
        {

            con3.Open();
            SqlCommand cmd3 = new SqlCommand("insert into ...", con3);
            cmd3.ExecuteNonQuery();
            con3.Close();
        }
    }
}

Now it is storing the value in the database of the TextBox whose respective CheckBox is Checked

Hanumendra
  • 309
  • 2
  • 9
  • 22