简体   繁体   中英

For loop is looping incorrectly for controls in tablelayoutpanel

I have got a for loop to loop through controls in a TableLayoutPanel . In the TableLayoutPanel , there is a series of questions and the user need to tick one of the four Checkbox es to answer that question. The first question is visible, upon ticking an answer, the second question and its Checkbox es become visible. and so on till the 9th question, which ends the form.

At the end there is a Save button where the back-end code has a for loop to loop through all the checkboxes in the tablelayoutpanel to check which checkboxes are checked which are not checked.

When the loop starts running, it starts checking the Checkbox es in the second column, not from the first, not from the beginning. The first column Checkbox es are checked at the end of the loop, which is messing up the order.

Here is the for loop

foreach (Control control1 in tableLayoutPanel1.Controls.OfType<CheckBox>())
{

    CheckBox checkBox = (CheckBox)control1;
    String s = checkBox.Name;

    //boolean value for checkbox if is checked or not
    bool value = checkBox.Checked;

     listValue.Add(value);
}

Why is that happening, what can be done to force the loop to start at the first column Checkbox es?

When checking the debugger I saw controls added with the designer will take space [0] of the array of controls. So if I add button1, 2 and 3 and run a foreach, I will see button 3 first.

无文字

(Added 2 buttons, then 3 checkbox's so its in 'reversed' order by default)

I have found a solution for this, this way you have to name your checkbox's with numbers corresponding to the question number though.

int amountOfQuestions = 3; 
int index = 0;
while ( index < amountOfQuestions )
{
    index++;
    var checkbox = (CheckBox) this.Controls.Find( "CheckBox" + index, false ).First();
    var value = checkbox.Checked;
}

You can also add the CheckBox's in an array, that way you decide the order and can add one in between without a hassle:

CheckBox[] checkBoxArray = { checkBox1, checkBox2, checkBox3 };
//Add the checkbox's in the array in the order you want
foreach ( CheckBox checkBox in checkBoxArray )
{
    var value = checkBox.Checked;
}

Here is a solution, where you can enumerate the check boxes one of 2 ways, either by the Y coordinate in the table or the row number in the table.

tableLayoutPanel1.Controls.Add(new CheckBox(), 0, 0);
tableLayoutPanel1.Controls.Add(new CheckBox(), 0, 1);
tableLayoutPanel1.Controls.Add(new CheckBox(), 0, 2);
tableLayoutPanel1.Controls.Add(new CheckBox(), 0, 3);
tableLayoutPanel1.Controls.Add(new CheckBox(), 0, 4);

// Option 1
// Enumerate controls in order of height (from first to last on the form)
foreach (var checkBox in tableLayoutPanel1.Controls.OfType<CheckBox>().OrderBy(c => c.Location.Y))
{
    // ...
}

// Option 2
// Enumerate controls based on what row they are in the tabletLayoutPanel
foreach (var checkBox in tableLayoutPanel1.Controls.OfType<CheckBox>().OrderBy(c => tableLayoutPanel1.GetRow(c)))
{
    // ...
}

You can just loop through the cells:

for (int y = 0; y < tlp.RowCount; ++y) {
  for (int x = 0; x < tlp.ColumnCount; ++x) {
    CheckBox cb = tlp.GetControlFromPosition(x, y) as CheckBox;
    if (cb != null) {
      MessageBox.Show(cb.Name);
    }
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM