在Windows窗体中迭代用户控件时出现的问题

时间:2019-05-03 04:47:04

标签: c# winforms user-controls

在运行Windows窗体中的所有用户控件时遇到问题。

我正在创建具有以下功能的Windows窗体:

  1. 主窗体中嵌入了3个用户控件
  2. 主窗体还具有一个组合框。在“组合”框中选择一个特定的值会将相应的用户控件置于最前面。
  3. 每个用户控件都有两个复选框和两个组合框。
  4. 用户可以通过主窗体的组合框召唤每个用户控件,并选中复选框和/或修改每个用户控件内的组合框
  5. 完成此操作后,将有一个按钮,按下该按钮将执行以下代码。该代码应该检查每个用户控件中已选中了哪些复选框,并执行一些功能:
private void button1_Click(object sender, EventArgs e)
        {
            foreach (Control c in this.Controls)
            {
                if (c is UserControl)
                {
                    foreach (Control ctl in c.Controls)
                    {

                        if (ctl is CheckBox && (ctl as CheckBox).Checked)
                        {
                            Indicator.Text = "It's in";
                        }
                    }
                }
            }
            //Some other code after this
         }

在这里,我包括了一个名为“指标”的文本框,该框显示编译器是否已进入特定的“ for”循环或“ if”块。而且我观察到最里面的“ if”并没有得到执行。

有人可以指出为什么会这样吗?

3 个答案:

答案 0 :(得分:0)

您需要一个递归算法,

void ProcessControls(Control ctrlContainer) 
{ 
    foreach (Control ctrl in ctrlContainer.Controls) 
    { 
        if (ctrl is CheckBox && (ctrl as CheckBox).Checked)
        {
             Indicator.Text = "It's in";
        }
        if (ctrl.HasChildren) 
            ProcessControls(ctrl); 
    } 
}

答案 1 :(得分:0)

我确实认为您最好在用户控件中添加一些功能,以便它可以描述其自己的复选框的状态,而不是深入挖掘其中的复选框来查找并执行逻辑。通常,在OO编程中,当我们将内容封装在一个类中时,我们还提供“外部可见”的通用访问器来描述内部事务状态,而不是让外部代码兴趣在类内部四处寻找它们想要的东西

有时,您已经直接在设计器中或以编程方式将这些用户控件添加到了表单中。在第一种情况下,它们将具有自己的名称:

var u1 = usercontrol1.GetCheckboxStateArray();
var u2 = usercontrol2.GetCheckboxStateArray();

或者您可以通过编程方式添加它们,在这种情况下,在添加它们时在列表中跟踪它们很有意义:

protected List<UserControl> _ucList = new List<UserControl>();
...
foreach(var result in somedatabasequery){
  var uc = new UserControl(result.Whatever);
  this.Controls.Add(uc);
  _ucList.Add(uc);
}

然后可以迭代此列表。当然,您可能会说:“。Controls也是一个集合,所以当它们已经在可访问的集合中时,为什么还要将它们添加到另一个列表中” –出于您在这里的原因; .Controls是表单上所有控件的层次结构的通用描述,它包含我们不想要的东西,并且很难进行迭代。该列表纯粹是全部,只是我们感兴趣的内容

顺便说一句,您所描述的UI是非典型的。在选择保存一些文本的情况下,隐藏和显示控件的更常见方法是TabControl。如果您坚持使用这种“在控件集合中搜索UserControl”的方法,循环遍历也可能会更容易-tabcontrols有tabpages,tabpages可能会有一个仅包含UserControl的.Controls。标签页本质上是在单击页面时显示和隐藏控件,这可以简化您的代码

答案 2 :(得分:0)

感谢大家的回答。碰巧的是,这个问题一直隐藏在我的鼻子底下。在每个用户控件中,我都将复选框和组合框 放置在组框内 。它完全让我忘了,以至于我什至没有在他们的问题中提到他们。

因此,正如@Caius在评论中所建议的那样,该代码无法正常工作,因为我没有解决持有这些控件的Group Box Container。一旦删除了“组框”(仅用于美观目的),代码便开始正常运行。