重构代码... Controls.Find方法

时间:2010-06-25 06:50:45

标签: c# winforms refactoring

好的,我有一个代码(见下文):

    void M1()
    {
        for (int i = 1; i < 10; i++)
        {
            Control[] carr = this.Controls.Find("Number" +
                                                (i - 1).ToString() +
                                                "CheckBox", true);

            if ((carr != null) && (carr.Length > 0))
            {
                CheckBox enableCB = carr[0] as CheckBox;

                enableCB.Checked = i % 2 == 0 ? true : false; // or any other value
            }
        }
    }

我不喜欢使用Controls.Find方法进行迭代。我可以用更简单的东西替换它吗?

PS:表格上显示的所有NumberXCheckBox(X&gt; = 0和X&lt; = 8)。

启用LINQ,.net 3.5,Visual Studio 2008。

5 个答案:

答案 0 :(得分:4)

您可以将CheckBox控件包装在容器中,而不是按名称搜索,这意味着您可以遍历容器中的控件吗?

答案 1 :(得分:1)

如果您使用3.5或有其他LINQ可用,您可以执行以下操作

for ( int i = 0; i < 9; i++) {
  var control = this.Controls
    .Find(String.Format("Number{0}Checkbox", i))
    .Cast<CheckBox>()
    .FirstOrDefault();
  if ( control != null ) {
    control.Checked = (i % 2) != 0;
  }
}

答案 2 :(得分:1)

我建议您在类型中引入一个字段以保留对复选框的引用(数组,列表,字典 - 您选择。)这样您就不再需要使用此非类型和有点丑陋的发现 - 按键控制方法。

无论如何,如果你仍然使用.NET 2.0并且更喜欢使用Find方法,那么你可以简化一下你的循环:

for (var i = 0; i <= 8; i++)
{
    var controls = Controls.Find("Number" + i + "CheckBox", true);
    if (controls.Length > 0)
    {
        var checkBox = controls[0] as CheckBox;
        if (checkBox != null)
            checkBox.Checked = i%2 == 0;
    }
}

checkbox上的最新非无效性测试可能会被省略。

答案 3 :(得分:0)

更多linq-y

for (int i = 0; i < 10; i++) {
    var c = (from CheckBox c in this.Controls.Find(String.Format(CultureInfo.InvariantCulture, "Number{0}CheckBox", i-1), true)
             select c).FirstOrDefault();
    if (c != null) {
        c.Checked = i % 2 == 0 ? true : false;
    }
}

答案 4 :(得分:0)

这是没有linq的,但是稍微清理了一下代码。

for (int i = 1; i < 10; i++)
{
    Control[] carr = this.Controls.Find("Number" + (i - 1) + "CheckBox", true);
    if (carr.Length <= 0) continue;
    CheckBox enableCB = carr[0] as CheckBox;
    enableCB.Checked = (i % 2) == 0;
}

[编辑:添加了查找(..)代码以显示您不必检查空的原因]

这是Find函数的框架内部代码。我在其中添加了几条评论

public Control[] Find(string key, bool searchAllChildren)
{
   if (string.IsNullOrEmpty(key))
   {
       throw new ArgumentNullException("key", SR.GetString("FindKeyMayNotBeEmptyOrNull"));
   }
   // Will always return an ArrayList with zero or more elements
   ArrayList list = this.FindInternal(key, searchAllChildren, this, new ArrayList());
   // Will always return an Array of zero or more elements
   Control[] array = new Control[list.Count];
   list.CopyTo(array, 0);
   return array;

}