动态生成按钮点击时触发对象引用未设置实例错误的技术求助
解决按钮点击时“对象引用未设置为对象的实例”错误
嘿,这个问题我太熟了!你遇到的错误根源非常清晰——事件处理程序里的drow变量是循环中的局部变量,当循环执行完毕后,这个变量已经超出了它的作用域,不再指向任何有效的DataRow对象。当你点击按钮触发事件时,再去访问drow(0)自然会报对象引用为空的错误。
下面是具体的修复方案,同时还会优化你的代码安全性:
步骤1:给每个按钮绑定对应的商品编号
在创建按钮的循环里,把当前行的商品编号存储到按钮的Tag属性中——这个属性就是用来存储控件关联的自定义数据的,非常适合这种场景:
Dim b As New Button() With b .Location = New System.Drawing.Point(350, 40 * i) .Enabled = True .Width = 100 .Text = "fill stock" .Tag = drow(0) ' 将当前商品编号绑定到按钮的Tag属性 Panel3.Controls.Add(b) AddHandler b.Click, AddressOf Me.Button_Click End With
步骤2:修改事件处理程序,从按钮中获取商品编号
在点击事件里,通过sender参数获取触发事件的按钮,再从它的Tag属性中取出商品编号,同时一定要用参数化查询代替字符串拼接(避免SQL注入漏洞),还要确保数据库连接一定会关闭:
Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) ' 先把sender转换成Button类型,获取当前点击的按钮 Dim clickedBtn As Button = DirectCast(sender, Button) ' 从Tag属性中取出商品编号 Dim targetNumArt As String = clickedBtn.Tag.ToString() Dim co As New SqlConnection("server=JAMMINGJACK-PC\SQLEXPRESS ;initial catalog=td3;integrated security=true;") Try Dim cmd As New SqlCommand() co.Open() cmd.Connection = co ' 使用参数化查询,彻底避免SQL注入风险 cmd.CommandText = "Update article set qteStck=(qteStck+(seuilmin*3)) where numart=@NumArt" ' 添加参数并赋值 cmd.Parameters.AddWithValue("@NumArt", targetNumArt) cmd.ExecuteNonQuery() MsgBox("库存补充成功!", MsgBoxStyle.Information, Me.Text) Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Critical, Me.Text) Finally ' 无论是否发生异常,都确保数据库连接关闭 If co.State = ConnectionState.Open Then co.Close() End If End Try End Sub
额外说明
Tag属性可以存储任何类型的对象,如果你知道numart是整数类型,也可以直接存储为Integer,后续转换时用CInt(clickedBtn.Tag)即可。- 参数化查询不仅更安全,还能避免因为编号包含特殊字符(比如单引号)导致的SQL语法错误。
- 使用
Finally块关闭连接是最佳实践,防止因为异常导致连接一直处于打开状态,消耗数据库资源。
内容的提问来源于stack exchange,提问作者Lamine
相关产品推荐
相关产品推荐

