-1

I am trying to programatically generate buttons and add event handlers to them and i've succeeded in creating the buttons but when I click on one of the I get the following message object reference not set to an instance of an object .

Here is the code that creates the buttons:

    Dim i As Integer = 1
    For Each dtab As DataTable In ds.Tables
        For Each drow As DataRow In dtab.Rows
            If (CInt(drow(3)) < CInt(drow(4))) Then
                Dim l As New Label()
                With l
                    .Location = New System.Drawing.Point(30, 40 * i)
                    .Text = "product number  " & drow(0) & " has reached the minimal quantity"
                    .Width = 300
                    Panel3.Controls.Add(l)
                End With
                Dim b As New Button()
                With b
                    .Location = New System.Drawing.Point(350, 40 * i)
                    .Enabled = True
                    .Width = 100
                    .Text = "fill stock"
                    Panel3.Controls.Add(b)
                    AddHandler b.Click, AddressOf Me.Button_Click
                End With
                i = i + 1
            End If

        Next
    Next

the code that handels the button click is the following:

Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
    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
        cmd.CommandText = "Update article set qteStck=(qteStck+(seuilmin*3)) where numart=" & drow(0) '
        cmd.CommandType = CommandType.Text
        cmd.ExecuteNonQuery()
        co.Close()
    Catch ex As Exception
        MsgBox(ex.Message, MsgBoxStyle.Critical, Me.Text)
    End Try
End Sub
Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
Amine Hammou
  • 100
  • 9

1 Answers1

0

There are two big problems on this line in your event handler:

cmd.CommandText = "Update article set qteStck=(qteStck+(seuilmin*3)) where numart=" & drow(0) '

The first problem is the code is crazy vulnerable to sql injection attacks. It's a side-issue to the question, but this is IMPORTANT, and you should take a few minutes to Google parameterized queries and how to use them.

The second problem is with the drow(0) expression. That variable has no meaning in this method. It was scoped to the For Each loop in the code that created your buttons, but it has no meaning at all here. That this compiles at all means you either tried to re-declare it at the class level (which won't help; that will be a different drow variable) or turned Option Strict off, which is very poor practice.

There are several ways you can address this, such as encoding the drow(0) value in theTag property or inferring it from the Name. My preferred approach here would be to create a custom control that groups your label and button together.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • The tag property worked out perfectly, but I'm curious as to what did man by creating a custom control that groups the labels and the buttons together ? Could please elaborate more ? – Amine Hammou Jan 31 '18 at 15:04
  • It's a big topic (Google is your friend here). But basically, you create a new custom control in Visual Studio, and it gives you a panel. You drop a label and a textbox on the panel. Then you add a property for your drow(0) value, set up the event handler, expose whatever public properties you want to use (like .Text), and you can drop that on a form or create it in code in one step. – Joel Coehoorn Jan 31 '18 at 15:18