如何迭代Windows窗体控件

3
我有5个文本框和5个标签,命名如下:
  • text1, text2, text3, 等等。
  • label1, label2, label3, 等等。
我想做的是针对每一个文本框和标签应用相同的代码,而不必逐个编写。 我考虑像这样循环:
for (int i = 1; i <= 5; i++)
{
    try
    {
        tcpCLient.ConnectAsync(text(i).Text, 80);
        label(i).Text = "Online";
    }
    catch (Exception)
    {
        label(i).Text = "Offline";
    }
}

问题在于Visual Studio不允许我编译,出现错误提示"当前上下文中不存在名称为'text'的内容"

这个方法错了吗?你会怎么做呢?

非常感谢!


它是Web应用程序还是桌面应用程序,MVC,WinForms是什么? - Ehsan Sajjad
1
猜测这是WinForms,该窗体具有可以迭代的属性:https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.control.controls?view=netframework-4.8 但我实际上建议使用模型、控制器和绑定。 - Fildor
2
顺便说一下,那段代码无论如何都不会起作用。你试图将一个TcpClient实例连接到4个终端点? - Fildor
请问您是来自VB或JavaScript背景吗?这样更容易“说您的语言”… - Fildor
1
如果你想深入了解数据绑定,可以从这里开始:https://learn.microsoft.com/en-us/dotnet/framework/winforms/windows-forms-data-binding - Fildor
1
这是一个使用C#和Framework 4.8的桌面WinForms应用程序。我使用了Clint的方法来解决这个问题,但我会像@Fildor建议的那样研究一下绑定!只要我在TCP之后关闭它,它似乎也可以这样工作。 - Goosfraba
4个回答

2

好的,代码 label(i).Text 的格式不正确。看起来你试图使用参数 i 调用函数 label 并访问该结果的成员 Text

你可以这样做:

Label[] labels = { label1, label2, label3, label4, label5 };
TextBox[] textBoxes = { text1, text2, text3, text4, text5 };

for (int i = 0; i < 5; i++)
{
    try
    {
        tcpCLient.ConnectAsync(textBoxes[i].Text, 80);
        labels[i].Text = "Online";
    }
    catch (Exception)
    {
        labels[i].Text = "Offline";
    }
}

2

当前上下文中不存在名称为“text”的变量。

text[i].Text 只有当 text 类型实现了 IEnumerable 接口时才能这样做

您可以使用此方法枚举控件:

var labels = new List<Label> { label1, label2, label3};
var textBoxs = new List<TextBox> { text1, text2, text3};


for (int i = 1; i <= 5; i++)
{
    try
    {
        tcpCLient.ConnectAsync(textBoxs[i].Text, 80);
        labels[i].Text = "Online";
    }
    catch (Exception)
    {
        labels[i].Text = "Offline";
    }
}

非常感谢!这个解决了问题。我会记住枚举只能与数组一起使用的事实。 - Goosfraba
“枚举只能与数组一起使用”这种说法是不正确的。任何类都可以实现索引器。更不用说 List != 数组了。 - ASh
1
labels(i) is incorrect syntax for access by index. it should be labels[i] - ASh
@ASh,好的发现,已编辑。 - Clint

1
您可以通过 ControlCollection 迭代一个表单的 Controls
请参见 Form.ControlCollection
但要注意,这包括了 所有 控件。如果您想挑选特定的控件,则需要按类型和/或名称进行筛选。
不过,我强烈建议采用不同的方法。我会制作一个 UserControl 并结合 Binding 使用 MVC 模式。
还要注意,您的代码不会按预期工作,因为它似乎尝试将同一实例的 TcpClient 与4个不同的端点连接。

0
在Windows表单中,您可以迭代Forms.Controls以更自动化的方式获取所有标签和文本框。
示例:
List<TextBox> textBoxes = Controls.OfType<TextBox>()
    .Where(txt => txt.Name.StartsWith("text"))
    .ToList();

List<Label> labels = Controls.OfType<Label>()
    .Where(lbl => lbl.Name.StartsWith("label"))
    .ToList();

for (int i = 0; i < textBoxes.Count; i++)
{
    try
    {
        tcpCLient.ConnectAsync(text(i).Text, 80);
        labels[i].Text = "Online";
    }
    catch (Exception)
    {
        textBoxes[i].Text = "Offline";
    }
}

注意: 通过这种方式,您只能获取Form直接子级。如果文本框和标签是另一个父控件(例如Panel)的子级,则需要迭代该父控件的Controls属性。要遍历Form上的所有控件,请参见: 循环遍历表单上的所有控件,甚至包括组合框中的控件


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接