通过部分匹配控件名称找到多个控件

4

我目前有100多个标签,它们的名称如下:

labelNumber1 
labelNumber2 
labelNumber3 
labelNumber4 
....
labelLetter1
labelLetter2 
labelLetter3 
labelLetter4
....

我该如何找到所有控件名称中含有“Number”的标签? 与其手动输入labelNumber1.text = "hello",我希望能够一次性处理。

我尝试过正则表达式和foreach循环配合通配符,但未成功。 我也在msdn.microsoft.com上查阅过关于如何在控件中使用正则表达式的资料。


反映您的表单类。 - RadioSpace
请详细描述“查找所有标签控件”的要求。 - skalinkin
如果它们都是labelNumber#,那么你就知道可以使用<Control>.Name.Substring来提取数字或字母文本,因为它们都是6个字符。例如:foreach(Control t in form.Controls) t.Name.Substring(5, 6).Equals("Number") - Sorceri
使用foreach循环遍历form.Controls中的每个Control t,然后检查t.Name。你也可以使用Linq。 - libertylocked
你可以使用 this.Controls 集合来以编程方式找到它们,但是你想对它们做什么呢?假设结果是一个包含 textBox1textBox2comboBox1 的列表。然后呢?你想对所有选定的控件运行相同的逻辑吗? - Reza Aghaei
3个回答

5
你可以循环遍历表单的Controls集合,并检查每个控件的名称是否包含类似“Label”的内容。或者你还可以检查控件是否是TextBox,Label等类型。
例如:
foreach (Control control in form.Controls)
{
    if (control.Name.ToUpper().Contains("[Your control search string here]"))
    {
        // Do something here.
    }


    if (control is TextBox) {
        // Do something here.
    }
}

1
感谢您输入代码。这个效果非常好。我去掉了“ToUpper”的部分,现在它的表现就像我想要的一样。 :) - user2851021
是的,我只是使用了 ToUpper(),以防您的命名约定不同。您可以检查它是否包含“LABEL”,它将匹配您标签命名的任何大小写。如果您想要区分大小写,则只需删除 ToUpper()。 - ManoDestra

0

我知道这是一个老问题,但我现在在这里,并且:

  • 该问题询问如何搜索多个控件。此解决方案实际上适用于任何类型的控件。
  • OP在使用“Contains”或正则表达式之间存在冲突。我投票支持正则表达式!对于这种过滤器,string.Contains不是一个好主意,因为"CoolButton"中也有一个"Button"

无论如何,这是代码:

public List<TControlType> FindByPattern<TControlType>(string regexPattern)
  where TControlType:Control
{
   return Controls.OfType<TControlType>()
                  .Where(control => Regex.IsMatch(control.Name, regexPattern))
                  .ToList();
}

使用方法:

//some regex samples you can test out
var startsWithLabel = $"^Label"; //Matches like .StartsWith()
var containsLabel = "Label"; //Matches like .Contains()
var startsWithLabelEndsWithNumber = "^Label.*\\d+&"; //matches Label8sdf12 and Label8
var containsLabelEndsWithNumber = "Label.*\\d+&"; //matches MyLabelRocks83475, MyLabel8Rocks54389, MyLabel8, Label8
var hasAnyNumber= "^CoolLabel\\d+$"; //matches CoolLabel437627

var labels = FindByPattern<Label>("^MyCoolLabel.*\\d+&");
var buttons = FindByPattern<Button("^AveragelyCoolButton.*\\d+&");

0

您可以过滤控件列表,仅返回标签。您还需要确保名称大于11个字符。

        List<Label> allNumberLabels = new List<Label>();
        foreach (Label t in this.Controls.OfType<Label>())
        {                
            if (t.Name.Length > 11)
            {
                if (t.Name.Substring(5, 6).Equals("Number"))
                {
                    allNumberLabels.Add(t);
                }
            }
        }

我知道这是一个旧答案,你可能可以猜到评论的原因。我正在回复一个被标记为重复的不同问题。尽管此解决方案对于 OP 的示例是正确的,但它过于特定于该情况。我会称之为“过度拟合”,“高维护成本”,“低重用率”。我知道现在的你可能会同意 :) - Alexandru Clonțea
@AlexC. 不好意思,说实话我真的猜不到一年后为什么要回来。此外,这段代码并不是低重用性的,因为它是针对该用户问题实例的...就像这个论坛上的大多数答案一样。你因为它不符合你的要求而来投反对票,这太荒谬了。 - Sorceri
确切地说是7年。您可以进行一次简短的编辑,我将取消踩的评价。 - Alexandru Clonțea
这只是2个声望点,我坚持我的评论。因为SO建议我这样做,所以我想解释一下。这个社区不是关于优质内容吗? - Alexandru Clonțea
@AlexC,你知道这不是被采纳的答案,对吗?你真是一个特别的人。 - Sorceri
谢谢! :) 我是那种在添加答案或使用互联网上的代码之前会检查整个线程的人。我喜欢在让世界变得更美好的同时学习一些东西!这有什么不好吗? - Alexandru Clonțea

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