如何使用标签由字符串分配的标签ID分配文本?

时间:2018-11-17 15:53:02

标签: c# .net winforms .net-4.6.1

**目标:**
要写入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];
            }
        }
    }
}

我也咨询了这篇文章:
Use string variable content as label ID to update label.Text, I get error - 'string' does not contain a definition for 'Text'

2 个答案:

答案 0 :(得分:1)

您可以像这样简单地进行操作:

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

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

答案 1 :(得分:0)

for循环

首先,这是错误的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的情况可见(我们只是在字典中添加了一个null)。

然后使用它:

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


简化

我想我们可以做得更好。设计人员将为您的标签创建字段,您可以将它们添加到字典中:

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。数组可以做

在完成编写后,我注意到代码只需要由一个整数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处的数组。