2017-04-18 104 views
0

我有一个for循环来循环控制TableLayoutPanel中的控件。在TableLayoutPanel中,有一系列问题,用户需要勾选四个Checkbox中的一个来回答该问题。第一个问题是可见的,在答复答案时,第二个问题及其Checkbox变得可见。等到第九个问题结束时。For循环对于tablelayoutpanel中的控件循环不正确

最后有一个保存按钮,其中后端代码有一个for循环,循环遍历tablelayoutpanel中的所有复选框,以检查哪些复选框被选中而没有被选中。

当循环开始运行时,它开始检查第二列中的Checkbox es,而不是从第一列开始,而是从开始。在循环结束时检查第一列Checkbox es,这弄乱了顺序。

下面是for循环

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

,这是为什么发生,什么可以做,以强制循环的第一列Checkbox ES开始?

+0

而不是使用一个foreach()的,使用for循环和访问tableLayoutPanel.Controls [I]这种方式维护秩序,他们加入。 Foreach不保证在收集顺序中迭代。 – Mangist

+1

@Mangist foreach不应该以随机顺序神奇地运行 – EpicKip

+0

@Mezo如果你调试了复选框的索引是否像你预期的那样排序? – EpicKip

回答

0

这里是一个解决方案,在那里你可以枚举可以通过2种方式之一复选框,可以使用表格中的Y坐标或表格中的行数。

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))) 
{ 
    // ... 
} 
+0

这两个选项都能够使我获得第一列复选框,但没有按正确的顺序。它会先给我Checkbox3,然后Checkbox1,然后Checkbox4,然后Checkbox2。 – Mezo

+0

当您将复选框添加到表单时,是否在添加到tableLayoutPanel时为每个表单指定了行号?看看我是如何添加复选框,指定行0,1,2,3等 – Mangist

+0

它的工作原理,它只是在设计器代码中的复选框声明的顺序,这使得我所没有想到的差异。 tablelayoutpanel中的顶部复选框,在结尾处声明并分配列/行值。 – Mezo

1

当检查调试器时,我看到添加了设计器的控件将占用控件数组的空间[0]。所以如果我添加button1,2和3并运行一个foreach,我会首先看到按钮3。

NoText

(由2个按钮,然后3复选框的所以其在“逆转”默认顺序)

我已经找到了一个解决方案,这样一来,你必须命名您的复选框的对应数字到问题编号。

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

您还可以添加CheckBox的一个数组,你决定的顺序,可以在之间没有麻烦添加一个方法:

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

这可行,但我不确定依赖控件的名称是最好的方法。工作解决方案,我会给你,但保持它可能会很棘手。如果你想在调查中插入一个问题,那么你必须重新命名所有的复选框? – Mangist

+0

您也可以手动将它们添加到数组中,我将在明天插入该方法(现在睡眠时间) – EpicKip

0

您只需通过细胞循环:

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