是否可以在不使用循环的情况下找到控件?

Is it possible to find a control without using loop?

我在 FlowLayoutPanel 中有很多不同文本的按钮,我想找到具有特定字符串的按钮。

我目前是这样做的:

Dim str as String = 'some text
For each btn as Button in FlowLayoutPanel.Controls
    If btn.Text = str then
         'do something with btn
    End If
Next

是否可以这样做?

Dim str as String = 'some text
Dim btn as Button = FlowLayoutPanel.Controls.Button.Text with that string
'do something with btn

您可以使用 LINQ,例如

Dim btn = myFlowLayoutPanel.Controls.
                            OfType(Of Button)().
                            FirstOrDefault(Function(b) b.Text = myText)

请注意,无论所有子控件是否为 Buttons,该代码都将起作用,因为 OfType 确保忽略 Button 以外的任何内容。但是,如果您知道每个子控件都是 Button,那么这样做会更有效率:

Dim btn = myFlowLayoutPanel.Controls.
                            Cast(Of Button)().
                            FirstOrDefault(Function(b) b.Text = myText)

这样做效率更高:

Dim btn = DirectCast(myFlowLayoutPanel.Controls.
                                       FirstOrDefault(Function(b) b.Text = myText),
                     Button)

虽然差异可以忽略不计,但如果效率是您主要关心的问题,那么您可能根本不应该使用 LINQ。

另请注意,FirstOrDefault 仅适用于可能存在零个、一个或多个匹配项的情况。在其他情况下其他方法更合适:

First:总会有至少一场比赛,但也可能不止一场。

FirstOrDefault: 可能没有匹配项,也可能有多个匹配项。

Single: 总会有一个匹配。

SingleOrDefault:可能没有匹配项,但绝不会超过一个。

如果您使用 OrDefault 方法之一,则结果可能是 Nothing,您应该始终在使用前测试 Nothing 的结果。