VB开发:循环为相似命名TextBox赋值无效,求问题排查
问题分析与解决方案
问题描述
VB新手开发应用时,需要为48个命名规则为L1onHHxx、L1onMMxx、L1offHHxx、L1offMMxx(xx为1-24)的TextBox填充计算值,编写了异步点击事件代码后,验证用的Box1-4能正确显示控件名称,但目标TextBox始终无值显示,请求排查问题。
用户代码如下:
Private Async Sub Line1Calc_Click(sender As Object, e As EventArgs) Handles Line1Calc.Click Dim Cycle_Time As Integer Dim Cycle_Count As Integer Dim srtHH As Integer Dim srtMM As Integer Dim stpHH As Integer Dim stpMM As Integer Dim inDelay As Integer Dim i As Integer Dim lineONHH As New Label Dim lineONMM As New Label Dim lineOFFHH As New Label Dim lineOFFMM As New Label 'Dim controls = GetAllTextBoxes(Me) 'Line1Tab Cycle_Time = CInt(L1Time.Text) Cycle_Count = CInt(L1Count.Text) srtHH = CInt(L1ONHH.Text) srtMM = CInt(L1ONMM.Text) stpHH = CInt(L1OFFHH.Text) stpMM = CInt(L1OFFMM.Text) inDelay = (24 / CInt(Cycle_Count)) L1onhh1.Text = srtHH L1onhh1.Text = srtHH L1offhh1.Text = stpHH L1offmm1.Text = stpMM For i = 2 To (Cycle_Count) srtHH += inDelay stpHH += inDelay lineONHH.Name = "L1onhh" & i.ToString() lineONMM.Name = "L1onmm" & i.ToString() lineOFFHH.Name = "L1offhh" & i.ToString() lineOFFMM.Name = "L1offmm" & i.ToString() lineONHH.Text = srtHH lineONMM.Text = srtMM lineOFFHH.Text = stpHH lineOFFMM.Text = stpMM ' To Check if the labels name are correct Box1.Text = lineONHH.Name Box2.Text = lineONMM.Name Box3.Text = lineOFFHH.Name Box4.Text = lineOFFMM.Name Await Task.Delay(1000) Next End Sub
问题原因
- 核心错误:操作的是新控件而非界面已有控件
代码中Dim lineONHH As New Label等语句是新建了Label对象,并非引用界面上已存在的TextBox控件。修改这些新对象的名称和文本,完全不会影响界面上的目标TextBox,所以控件始终无值显示。 - 次要错误:整数除法导致精度丢失
inDelay = (24 / CInt(Cycle_Count))用Integer类型存储除法结果,会直接丢弃小数部分,导致时间计算逻辑错误。
修正后的代码
Private Async Sub Line1Calc_Click(sender As Object, e As EventArgs) Handles Line1Calc.Click Dim Cycle_Time As Integer Dim Cycle_Count As Integer Dim srtHH As Double ' 改用Double存储,避免精度丢失 Dim srtMM As Integer Dim stpHH As Double Dim stpMM As Integer Dim inDelay As Double ' 改用Double类型 Dim i As Integer 'Line1Tab Cycle_Time = CInt(L1Time.Text) Cycle_Count = CInt(L1Count.Text) srtHH = CDbl(L1ONHH.Text) srtMM = CInt(L1ONMM.Text) stpHH = CDbl(L1OFFHH.Text) stpMM = CInt(L1OFFMM.Text) inDelay = 24 / Cycle_Count ' 直接用Cycle_Count,已为Integer类型 ' 直接操作第一个控件 L1onhh1.Text = srtHH.ToString() L1onmm1.Text = srtMM.ToString() L1offhh1.Text = stpHH.ToString() L1offmm1.Text = stpMM.ToString() For i = 2 To Cycle_Count srtHH += inDelay stpHH += inDelay ' 通过控件名称查找界面上已存在的TextBox Dim lineONHH As TextBox = DirectCast(Me.Controls.Find("L1onhh" & i.ToString(), True)(0), TextBox) Dim lineONMM As TextBox = DirectCast(Me.Controls.Find("L1onmm" & i.ToString(), True)(0), TextBox) Dim lineOFFHH As TextBox = DirectCast(Me.Controls.Find("L1offhh" & i.ToString(), True)(0), TextBox) Dim lineOFFMM As TextBox = DirectCast(Me.Controls.Find("L1offmm" & i.ToString(), True)(0), TextBox) ' 设置文本值 lineONHH.Text = srtHH.ToString() lineONMM.Text = srtMM.ToString() lineOFFHH.Text = stpHH.ToString() lineOFFMM.Text = stpMM.ToString() ' 验证控件名称 Box1.Text = lineONHH.Name Box2.Text = lineONMM.Name Box3.Text = lineOFFHH.Name Box4.Text = lineOFFMM.Name Await Task.Delay(1000) Next End Sub
关键改动说明
- 将
srtHH、stpHH、inDelay改为Double类型,避免整数除法导致的精度丢失; - 使用
Me.Controls.Find()方法根据名称递归查找界面上已存在的TextBox控件(第二个参数True表示查找子容器内的控件); - 设置文本时将数值转为字符串,避免类型不匹配错误。
内容的提问来源于stack exchange,提问作者Arya Digital
相关产品推荐
相关产品推荐

