Рефакторинг этого кода ... Метод Controls.Find - PullRequest
2 голосов
/ 25 июня 2010

ОК, у меня есть код (см. Ниже):

    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> = 0 и X <= 8) представлены в форме. </p>

LINQ включен, .net 3.5, Visual studio2008

Ответы [ 5 ]

4 голосов
/ 25 июня 2010

Вместо поиска по имени, можете ли вы обернуть свои CheckBox элементы управления в контейнер, что означает, что вы можете просто перебирать элементы управления в контейнере?

1 голос
/ 25 июня 2010

Я бы посоветовал вам ввести поле в вашем типе для хранения ссылок на ваши флажки (массив, список, словарь - вы выбираете.) Таким образом, вам больше не нужно будет использовать этот нетипизированный и несколько уродливый метод поиска по ключу.

В любом случае, если вы все еще в .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, вероятно, может быть опущен.

1 голос
/ 25 июня 2010

Если вы используете 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;
  }
}
0 голосов
/ 25 июня 2010

Вот один без 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 (..), чтобы показать, почему вам не нужно проверятьдля нуля]

Вот внутренний код фреймворков для функции 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;

}

0 голосов
/ 25 июня 2010

Больше 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...