Как назначить текст метке с идентификатором метки, назначаемым строкой? - PullRequest
0 голосов
/ 17 ноября 2018

Цель:
Для записи в label text, но метка ID назначается строкой.

Проблема:
Не работает, ошибок нет.В большинстве мест я искал ответ, но ничего не помогло!

Мой код:

string asdfj = treeView2.SelectedNode.Text;
string adqien = System.IO.Path.Combine(dir7, asdfj);
string[] tnsop = System.IO.File.ReadAllLines(@adqien);
h1a.Text = "100";
for (int o = 2; o > 6; o++)
{
    //This is the label name e.g "h2a',h3a" etc
    string tempc = string.Format("h" + o.ToString() + "a");

    foreach (Control ctr in this.Controls)
    {
        if (ctr is Label)
        {
            if (ctr.Name == tempc)
            {
                ctr.Text = tnsop[o];
            }
        }
    }
}

Я также обращался к этому посту:
Используйте строковую переменную в качестве идентификатора метки для обновления метки. Текст, я получаю ошибку - «строка» не содержит определения для «Текст»

Ответы [ 2 ]

0 голосов
/ 17 ноября 2018

Цикл для

Прежде всего, это неправильно for (int o = 2; o > 6; o++).

Он начинается с o = 2, затем проверяет, является ли o > 6 ложным, потому что o = 2, а затем пропускает цикл.

Полагаю, вы хотели написать: for (int o = 2; o < 6; o++). Я не уверен в этом, исправьте это как подходящее.

Приложение : Это можно было бы легко обнаружить путем отладки и перехода. Вы можете начать с добавления точки останова в свой код (в Visual Studio вы можете поместить курсор на нужную строку и нажать F9 - по умолчанию), а затем запустить в отладчике. Когда строка с точкой останова достигнута, отладчик останавливает выполнение и позволяет вам проверить значения переменных, стека вызовов и т. Д. Затем вы можете перейти с помощью F10 или F11 (если вы хотите внутри вызова метода) и посмотрим, как развивается код. Вы заметите, что он не входит в цикл for.


Поиск ярлыков

Если поиск метки по-прежнему не работает, я предполагаю, что проблема заключается в том, что метки не находятся непосредственно в форме или у них нет заданного имени.

Вы можете использовать this.Controls.Find(name, searchAllChildren), чтобы получить нужные вам ярлыки.

То есть:

string labelName = string.Format("h" + o.ToString() + "a");
Control[] control = this.Controls.Find(labelName, true);

Примечание: Да, я могу понять, что это название ярлыка по тому, как вы его используете. Использование комментария, чтобы сказать мне, экономит некоторое время ... однако, пожалуйста, используйте лучшие имена переменных. Вам не понадобится комментарий, чтобы сказать мне, что это имя метки, если имя переменной так говорит.

Вам все еще нужно проверить его на ярлык:

string labelName = string.Format("h" + o.ToString() + "a");
Control[] controls = this.Controls.Find(labelName, true);
foreach (Control control in controls)
{
    if (control is Label) // if (control.GetType() == typeof(Label))
    {
       // ...
    }
}

Создание словаря

Однако я бы не советовал делать это каждый раз. Вместо этого я предлагаю создать словарь:

Dictionary<string, Label> labels;

// ...

labels = new Dictionary<string, Label>();

for(int o = 2; o < 6; o++)
{
    string labelName = string.Format("h" + o.ToString() + "a");
    Label label = GetLabel(labelName);
    labels.Add(labelName, label);
}

// ...

private Label GetLabel(string labelName)
{
    Control[] controls = this.Controls.Find(labelName, true);
    foreach (Control control in controls)
    {
        if (control is Label) // if (control.GetType() == typeof(Label))
        {
           return control as Label;
        }
    }
    return null;
}

Примечание : Я предлагаю сделать словарь полем и инициализировать его только один раз во время загрузки формы.

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

Это также сделает случай, когда Label не найден видимым (мы просто добавили ноль в словарь).

А затем используйте его:

string[] tnsop = System.IO.File.ReadAllLines(@adqien);
for (int o = 2; o < 6; o++)
{
    string labelName = string.Format("h" + o.ToString() + "a");
    label = labels[labelName];
    label.Text = tnsop[o];
}

Приведенный выше код должен выдавать NullReferenceException, если метка не была найдена при создании словаря.


Simplify

Я думаю, мы можем сделать лучше. Дизайнер создаст поля для ваших меток, вы можете просто добавить их в словарь:

Dictionary<string, Label> labels;

// ...

labels = new Dictionary<string, Label>();
labels["h2a"] = h2a;
labels["h3a"] = h3a;
labels["h4a"] = h4a;
labels["h5a"] = h5a;

// ...

string[] tnsop = System.IO.File.ReadAllLines(@adqien);
for (int o = 2; o < 6; o++)
{
    string labelName = string.Format("h" + o.ToString() + "a");
    label = labels[labelName];
    label.Text = tnsop[o];
}

Примечание : существует множество возможностей для более современного синтаксиса, включая инициализацию коллекции и ключевое слово var.

Приложение : Я развертываю цикл в приведенном выше коде, это нормально для удобства обслуживания, если число итераций мало, на самом деле это обычная оптимизация. Теоретически вы могли бы сделать это и для другого цикла.


PS. Массив будет делать

После завершения записи я заметил, что код нужно искать только по int o.

Мы можем переработать, чтобы использовать int для словарных ключей:

Dictionary<int, Label> labels;

// ...

labels = new Dictionary<int, Label>();
labels[2] = h2a;
labels[3] = h3a;
labels[4] = h4a;
labels[5] = h5a;

// ...

string[] tnsop = System.IO.File.ReadAllLines(@adqien);
for (int o = 2; o < 6; o++)
{
    label = labels[o];
    label.Text = tnsop[o];
}

Теперь у нас меньше конкатенаций и более простой код.

Мы могли бы использовать массив:

Label[] labels;

// ...

labels = new Label[4];
labels[0] = h2a;
labels[1] = h3a;
labels[2] = h4a;
labels[3] = h5a;

// ...

string[] tnsop = System.IO.File.ReadAllLines(@adqien);
for (int o = 2; o < 6; o++)
{
    label = labels[o - 2];
    label.Text = tnsop[o];
}

Обратите внимание, что я сместил индексы, чтобы иметь возможность использовать массив из индекса 0.

0 голосов
/ 17 ноября 2018

Вы можете сделать это просто так:

this.Controls.Find(labelname).Text = Value;

или

this.Controls.OfType<Label>().FirstOrDefault(x => x.Name == labelName).Text = Value;
...