Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

I have made a button click handler to be generic to enable it to handle two buttons.

 

One button saves a record to the transactions table and the other to the transactions_weekly table.

 

Now if the record begin saved when running a call to the event handler for the transactions is of type "SHOPPING" the app prompts the user to ask do they want it also saved to the transactions_weekly table.

 

If the answer is yes I believe I need to recall the event handler I am currently in?

 

So to do this I create an object reference to the button on the form that would save a transaction_weekly record and then call the click event and pass it the reference object.

 

Problem is the error appears saying that objSender is not initialised when an attempt is made to reference it?

 

Am on on the right track or totally off beam?

 

   Private Sub btnSaveTransaction_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
   Handles btnSaveTransaction1.Click, btnSaveTransaction2.Click

       ' check to see if a valid entry has been made

       If Not ValidateEntry(sender) Then

           Exit Sub

       End If

       ' create a control object to access the name of the button making the call

       Dim ctlSender As Control = DirectCast(sender, System.Windows.Forms.Control)

       ' controls to make this sub generic

       Dim ctlDateTimePicker As New DateTimePicker, ctlComboBox As New ComboBox, ctlTextBox As New TextBox

       Dim ctlCheckBox1 As New CheckBox, ctlCheckBox2 As New CheckBox

       ' create an SQL command object to write changes to the database

       Dim cmdTransactions As New System.Data.SqlClient.SqlCommand

       ' string to pass table name to dynamic sql

       Dim strTableName As String = ""

       ' object to reference the save button on the transactions weekly page

       Dim objSender As Object = DirectCast(Me.Controls("btnSaveTransaction2"), Object)

       ' query callers name to setup the sql staement and controls

       Select Case ctlSender.Name

           Case "btnSaveTransaction1"

               strTableName = "transactions"

               cmdTransactions.CommandText = "INSERT INTO transactions (tran_date, tran_id, tran_amount, tran_balance, tran_save, " & _
                                             "tran_withdrawal) VALUES (@TransDate, @TransDesc, @TranAmount, 0, @Saved, @WithDraw)"

               ctlDateTimePicker = Me.dtmTransDate1

               ctlComboBox = Me.cboTransDescription1

               ctlTextBox = Me.txtAmount1

               ctlCheckBox1 = Me.chkSave

               ctlCheckBox2 = Me.chkWithDraw

               ' detailed monthly has these but detailed weekly does not

               cmdTransactions.Parameters.Add("@Saved", SqlDbType.Decimal).Value = ctlCheckBox1.Checked

               cmdTransactions.Parameters.Add("@WithDraw", SqlDbType.Decimal).Value = ctlCheckBox2.Checked

               ' when the transaction type is shopping ask do we want to save to transactions weekly also

               If ctlComboBox.Text = "SHOPPING" Then

                   If MessageBox.Show("Do you want this transaction written to the weekly transaction page", _
                                      "Copy Transaction", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) _
                                      = Windows.Forms.DialogResult.Yes Then

                       ' set the fields on the transactions weekly page to the ones on the transaction page
                       ' so when we call this event handler the values will be there as if the user had entered them

                       Me.dtmTransDate2.Text = ctlDateTimePicker.Text

                       Me.txtAmount2.Text = ctlTextBox.Text

                       Me.cboTransDescription2.Text = ctlComboBox.Text

                       ' simulate the user clicking the save button on the transactions weekly page

                       btnSaveTransaction_Click(objSender, e)

                       ' reset the transactions weekly fields

                       Me.dtmTransDate2.Text = Now.ToString

                       Me.txtAmount2.Text = ""

                   End If

               End If

           Case "btnSaveTransaction2"

               strTableName = "transactions_weekly"

               cmdTransactions.CommandText = "INSERT INTO transactions_weekly (tran_date, tran_id, tran_amount, tran_balance) " & _
                                             "VALUES (@TransDate, @TransDesc, @TranAmount, 0)"

               ctlDateTimePicker = Me.dtmTransDate2

               ctlComboBox = Me.cboTransDescription2

               ctlTextBox = Me.txtAmount2

       End Select

       Try

           ' link the command to the database connection

           cmdTransactions.Connection = glb_cnMB2007

           ' add the parameters to the command

           cmdTransactions.Parameters.Add("@TransDate", SqlDbType.DateTime).Value = ctlDateTimePicker.Text

           cmdTransactions.Parameters.Add("@TransDesc", SqlDbType.VarChar).Value = ctlComboBox.SelectedValue.ToString

           cmdTransactions.Parameters.Add("@TranAmount", SqlDbType.Decimal).Value = ctlTextBox.Text

           ' if the record was appended successfully then update the transaction display

           If cmdTransactions.ExecuteNonQuery() = 1 Then

               ' refresh the rolling balance in transaction table

               CalculateRollingBalance(strTableName)

               If Not RefreshTransactionLists(Me.tbcMain.SelectedIndex) Then

                   Me.Controls("btnSaveTransaction" & Me.tbcMain.SelectedIndex).Enabled = False

                   Me.Controls("btnClearTransaction" & Me.tbcMain.SelectedIndex).Enabled = False

               End If

           End If

           ' reset the transaction fields

           ctlDateTimePicker.Value = Now

           ctlTextBox.Text = ""

           ctlTextBox.Select()

       Catch objError As Exception

           ' tell user no connection made

           MessageBox.Show("Failed to save transaction to the database" & vbCrLf & vbCrLf & objError.Message, _
"Save Error", MessageBoxButtons.OK, MessageBoxIcon.Error)

       End Try

   End Sub

  • Administrators
Posted

Rather than explicity calling the btnSaveTransaction_Click(objSender, e) method directly you might want to use the PerformClick on the btnSaveTransaction2 control.

 

Also I notice you are creating a lot of controls in the code i.e.

Dim ctlDateTimePicker As New DateTimePicker, ctlComboBox As New ComboBox, ctlTextBox As New TextBox
Dim ctlCheckBox1 As New CheckBox, ctlCheckBox2 As New CheckBox

if you are going to assign existing controls to these variables you do not need the New keyword - this will prevent you creating the unused instances of the controls and will keep the memory utilisation down.

 

In the line

Dim objSender As Object = DirectCast(Me.Controls("btnSaveTransaction2"), Object)

the direct cast isn't required as everything is an object and therefore the cast is always safe and going to succeed.

 

In the long run though it might be easier to have two separate methods - one to update the transactions table and one to update the transactions_weekly table and simply call the correct method(s) from the appropriate button click event.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Posted

Code refactoring

 

Generally, instead of using the same method to handle both clicks, I would suggest moving the shared code (code that would be executed by both handlers) to a seperate sub or function which is called by both handlers. Your Select block shows that there is quite a bit of button-specific code, so two handlers would make more sense. This would also allieviate your problem since the handlers would not need to check the sender parameter.

 

There are other ways you could refactor your code, such as putting the code for btnSaveTransaction2 into its own sub and calling it directly. Either way, I think some sort of refactoring would be the best solution, if only to make the code easier to understand.

 

As far as your current code goes:

 

  1. Dim objSender As Object = DirectCast(Me.Controls("btnSaveTransaction2"), Object)
    You never need to explicitly cast something to Object as all upcasts are implicit, and casting to Object is the ultimate upcast.
     
  2. I would suggest you use Me.controlname rather than Me.Controls("controlname") as this is more efficient, less prone to errors, and does not require a cast.

Never trouble another for what you can do for yourself.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...