.net 如何更改循环中具有相似设计名称的标签的文本属性?

.net 如何更改循环中具有相似设计名称的标签的文本属性?,.net,vb.net,.net,Vb.net,我的表单上的表格设计布局中有几个标签。我想一次更改标签组的文本属性,例如)包含TempID的所有标签。它们要更改的值存储在数组中,因此lblTempID.text=CustomerID(计数器)。我遇到的问题是,即使我获取表中包含TempID的所有标签的名称并将它们存储在一个数组中,我也不能使用.text方法,因为它不是字符串的属性。我尝试过的其他解决方案只是在表单加载时,所有标签都是白色矩形 感谢您的帮助 您需要将控件放入容器中 var labControls = new List<La

我的表单上的表格设计布局中有几个标签。我想一次更改标签组的文本属性,例如)包含
TempID
的所有标签。它们要更改的值存储在数组中,因此
lblTempID.text=CustomerID(计数器)
。我遇到的问题是,即使我获取表中包含
TempID
的所有标签的名称并将它们存储在一个数组中,我也不能使用
.text
方法,因为它不是字符串的属性。我尝试过的其他解决方案只是在表单加载时,所有标签都是白色矩形


感谢您的帮助

您需要将控件放入容器中

var labControls = new List<Label>();
labControls.Add(TempID1);
labControls.Add(TempID2);
labControls.Add(TempID3);
....
foreach(var lab in labControls)
{
     lab.Text = "new text";
}
var labControls=new List();
labControls.Add(TempID1);
labControls.Add(TempID2);
labControls.Add(TempID3);
....
foreach(labControls中的var实验室)
{
lab.Text=“新文本”;
}

使用Linq按名称获取标签

' say all the labels are directly on the form
' alternatively this could be a Panel, GroupBox, etc.
Dim container As Control = Me
' get all Labels in the container
Dim myLabels As IEnumerable(Of Label) = container.Controls.OfType(Of Label)
' get all labels with "TempID" in their name
Dim myLabelTempIDs As IEnumerable(Of Label) = myLabels.Where(Function(l) l.Name.Contains("TempID"))
' get the only label named exactly "lblTempID1"
Dim myLabelTempID1 As Label = myLabels.Where(Function(l) l.Name = "lblTempID1").Single()

For counter As Integer = 1 To 10
    Dim counterLocal = counter
    Dim myLabelTempID = myLabels.Where(Function(l) l.Name = $"lblTempID{counterLocal}").Single()
    myLabelTempID.Text = CustomerID(counter)
Next
用可拓方法

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' get all Labels in Me, using extension method defined below
        Dim myLabels As IEnumerable(Of Label) = Me.ChildControls(Of Label)

        For counter As Integer = 1 To 10
            Dim counterLocal = counter
            Dim myLabelTempID = myLabels.Where(Function(l) l.Name = $"lblTempID{counterLocal}").Single()
            myLabelTempID.Text = CustomerID(counter)
        Next
    End Sub

End Class

Public Module extensions

    <Runtime.CompilerServices.Extension()>
    Public Function ChildControls(Of T As Control)(ByVal parent As Control) As IEnumerable(Of T)
        Dim result As New List(Of T)
        For Each ctrl As Control In parent.Controls
            If TypeOf ctrl Is T Then result.Add(CType(ctrl, T))
            result.AddRange(ctrl.ChildControls(Of T)())
        Next
        Return result
    End Function

End Module
公共类表单1
私有子表单1_Load(发送方作为对象,e作为事件参数)处理MyBase.Load
'使用下面定义的扩展方法获取Me中的所有标签
将MyLabel设置为IEnumerable(属于标签)=Me.ChildControls(属于标签)
计数器为整数=1到10
Dim计数器本地=计数器
Dim myLabelTempID=myLabels.Where(函数(l)l.Name=$“lblTempID{counterLocal}”).Single()
myLabelTempID.Text=CustomerID(计数器)
下一个
端接头
末级
公共模块扩展
公共函数ChildControls(属于T的控件)(ByVal parent作为控件)作为IEnumerable(属于T的)
Dim结果作为新列表(共T个)
对于父控件中的每个ctrl As控件
如果TypeOf ctrl是T,那么result.Add(CType(ctrl,T))
result.AddRange(ctrl.ChildControls(Of T)()
下一个
返回结果
端函数
端模块

老实说,我不明白为什么其他人把这件事弄得这么复杂(无意冒犯,但这是真的)

使用and(
Me
是当前表单),您可以非常轻松地访问顺序命名的标签

'Assuming you have 50 labels:
For i = 1 To 50
    Dim FoundControls As Control() = Me.Controls.Find("lblTempID" & i, True) 'Find the label with the name "lblTempID#" - where # is the current index (1-50).
    If FoundControls.Count > 0 Then 'Was a label found?
        FoundControls(0).Text = CustomerID(i) 'Change its text.
    End If
Next
这将递归地查找标签(这意味着它甚至会在子容器(如面板和组框)中查找标签),并更改找到的标签的文本

唯一的反面是,如果有多个标签具有完全相同的名称,但位于不同的容器中,那么这只会更改它找到的第一个标签的文本。因此,只要您的标签具有唯一的名称,就可以正常工作

  Dim LabelControls = New List(Of Label)
    LabelControls.Add(lblTempID1)
    LabelControls.Add(lblTempID2)
    LabelControls.Add(lblTempID3)
    LabelControls.Add(lblTempID4)
    LabelControls.Add(lblTempID5)
    LabelControls.Add(lblTempID6)
    LabelControls.Add(lblTempID7)
    LabelControls.Add(lblTempID8)
    LabelControls.Add(lblTempID9)
    LabelControls.Add(lblTempID10)  

 For Each label In LabelControls
        If label.Name.Contains("lblTempID") Then
            For counter = 0 To 9
                LabelControls(counter).Text = CStr(TempCustomerID(counter))
            Next

它与前面的答案非常相似(如果不是完全相同的话),但它做了我现在需要它做的事情

除了最后一行之外,我还了解如何分配每个标签的文本属性,因为它们都将不同?您是否有任何与标签上的后缀相对应的内容(我假设有后缀)?是的,它们都有“TempID”,但每个后面都有一个整数。TempID1、TempID2等。您使用的是哪个版本的visual studio?我使用的是visual studio 2017我不明白这是什么功能?请原谅我缺乏知识,我已经编码不到几个月了。我把标签放进一个容器里。然后您可以通过循环或索引访问它们-
labControls[0]
是列表中的第一个。谢谢您,先生,我将尝试这个!在将来向表单添加新标签时,此解决方案实际上为您提供了另一项任务:您还必须记住将控件添加到列表中@VisualIncent发布了最佳解决方案,它将自动找到与名称动态匹配的所有控件。(我的也可以转换为标签:)但可能有点过于复杂)。是的,这比较简单,但需要手动操作。我觉得其他的解决方案掩盖了正在发生的事情的本质,太神奇了。我建议,一旦你理解了基本的想法,那么也许可以改用比我的答案简单得多的加载容器的神奇方式。谢谢,我没想过用recursion@Tom:欢迎使用堆栈溢出!稍后,请按帖子左侧的勾号/复选标记,将解决问题的答案标记为已接受。有关更多信息,请参阅:@Visual Vincent问题已解决,但我手头有一个新问题。所有控件都显示为白色矩形,似乎抖动/闪烁,刷新表单时会正确显示它们,但我无法按任何按钮/与表单交互。@djv:您也找到了一个很好的解决方案。它整洁且相当灵活,尽管在新的程序员眼中可能有点复杂?;)很高兴您找到了自己的解决方案,但是有几件事需要指出:1)您不需要检查每个标签的名称,因为您只是将
lblTempID
标签添加到列表中。2) 跳过LabelControls循环中每个标签的第一个
。目前,由于您有两个循环,因此正在迭代标签10^10次。3) 将循环更改为:
For counter=0 to LabelControls.Count-1
,这样它将适应列表中标签的数量(使以后添加/删除标签更容易)。--快乐编码!;)