< Day Day Up > |
Click Event Code for the Form's ButtonsThe buttons on the form give the users the options they need. We'll discuss the code one routine at a time. Listing 4.8 shows the code for the Click event of the Add button. Listing 4.8. The Add Button Click Event CodePrivate Sub btnAdd_Click( _ ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles btnAdd.Click Try dsOneRecord.Clear() BindingContext(dsOneRecord, MainTable).AddNew() ClearFields() Inputs(TurnOn) Catch oEx As Exception MsgBox("Error: " + oEx.Message) End Try End Sub Private Sub btnEdit_Click( _ ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles btnEdit.Click Inputs(TurnOn) End Sub Private Sub btnDelete_Click( _ ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles btnDelete.Click Try BindingContext(dsOneRecord, MainTable).RemoveAt(0) Dim cb As OleDb.OleDbCommandBuilder cb = New OleDb.OleDbCommandBuilder cb.DataAdapter = daOneRecord daOneRecord.UpdateCommand = cb.GetUpdateCommand() daOneRecord.Update(dsOneRecord, MainTable) dsOneRecord.Tables(MainTable).AcceptChanges() LoadTheList() MsgBox("Record deleted", MsgBoxStyle.Information, "My app") Catch oEx As Exception MsgBox("Error: " + oEx.Message) End Try End Sub How the Button Code WorksThe Add button clears the text boxes and uses a BindingContext object to do the FoxPro equivalent of APPEND BLANK . Because the fields aren't bound to the data row in this exercise, I have to manually blank the onscreen controls, and finally I have to enable them. Edit is much simpler, of course. Listing 4.9 shows the code for the Click event of the Delete button. Listing 4.9. The Delete Button Click Event CodePrivate Sub btnDelete_Click( _ ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles btnDelete.Click Try BindingContext(dsOneRecord, MainTable).RemoveAt(0) Dim cb As OleDb.OleDbCommandBuilder cb = New OleDb.OleDbCommandBuilder cb.DataAdapter = daOneRecord daOneRecord.UpdateCommand = cb.GetUpdateCommand() daOneRecord.Update(dsOneRecord, MainTable) dsOneRecord.Tables(MainTable).AcceptChanges() LoadTheList() MsgBox("Record deleted", MsgBoxStyle.Information, "My app") Catch oEx As Exception MsgBox("Error: " + oEx.Message) End Try End Sub How btnDelete Click WorksBecause the recordset is disconnected from the data source, I have two separate tasks : First, I mark the record deleted using the BindingContext object; then I use a CommandBuilder object to construct a Delete command object and use the Update method of the DataAdapter object to pass it back to the data source. After updating the data source, I accept the changes to the dataset, clearing it, and reload the list using a call to LoadTheList() . You can't call a .Click method directly in Visual Basic .NET as you can in FoxPro, so that's why LoadTheList is a separate routine called both here and in the LoadList_Click method. Listing 4.10 shows the code for the Click event of the Save button. Listing 4.10. The Save Button Click Event CodePrivate Sub btnSave_Click( _ ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles btnSave.Click Try BindingContext(dsOneRecord, MainTable).EndCurrentEdit() Dim FldName As String Dim NewKey As String Dim Ctrl As Control For Each Ctrl In Controls If TypeOf Ctrl Is TextBox And Ctrl.Name <> "SearchValue" Then FldName = Ctrl.Name.Substring(3) 'skip characters 0-2 - thanks, Bill.. dsOneRecord.Tables(0).Rows(0).Item(FldName) = Ctrl.Text If FldName = KeyField Then NewKey = Ctrl.Text End If End If Next Dim cb As OleDb.OleDbCommandBuilder cb = New OleDb.OleDbCommandBuilder cb.DataAdapter = daOneRecord daOneRecord.UpdateCommand = cb.GetUpdateCommand() daOneRecord.Update(dsOneRecord, MainTable) dsOneRecord.Tables(MainTable).AcceptChanges() ' Load the list so as to include the new record LoadTheList() ' Find the new key in the list Dim str As String Dim I As Integer For I = 0 To ListBox1.Items.Count - 1 str = ListBox1.Items(I) If str.ToUpper.Substring(1).IndexOf(NewKey.ToUpper) > 0 Then ListBox1.SelectedIndex = I Exit For End If Next LoadaRecord() Inputs(TurnOff) Catch oEx As Exception MsgBox("Error: " + oEx.Message) End Try End Sub How btnSave Click WorksSaving the changes was the biggest challenge. First, I must end the current edit using the BindingContext object. Then, I have to put the values stored in the text properties of the onscreen controls back into the dataset. (I've fully qualified the row reference here so that you can see where it's going, but you can also use a DataRow object or even a DataTable object.) Next I build an Update command and execute it using the Update method. Again, I reload the list to reflect any changes or an added record. Finally, I want the record that I was just editing or adding to be selected when the save is completed, so that's what the last For..Next loop is about. When I find the SelectedIndex , I call LoadARecord and disable all of the input controls. Listing 4.11 shows the code for the Click event of the Cancel button. Listing 4.11. The Cancel Button Click Event CodePrivate Sub btnCancel_Click( _ ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles btnCancel.Click Try BindingContext(dsOneRecord, MainTable).CancelCurrentEdit() LoadaRecord() Inputs(TurnOff) Catch oEx As Exception MsgBox("Error: " + oEx.Message) End Try End Sub How btnCancel Click WorksThe Cancel command only requires that I cancel the current edit using the BindingContext object (which, by the way, also encapsulates the functionality of TableUpdate() , TableRevert() , DELETE , APPEND BLANK , TOP , BOTTOM , and SKIP ), reload the record I was editing, and disable the input fields. The last bit of code, which we saw at the beginning of this exercise, is shown in Listing 4.12. Listing 4.12. The Close Button Click Event CodePrivate Sub btnClose_Click( _ ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles btnClose.Click Close() End Sub How to Use This TemplateTo use this template in your projects, either copy it to a directory where you've started a solution, or use Add an Existing Project by right-clicking on the solution in the Solution Explorer and adding it to the solution. All you really need is InheritedForm.dll , but I recommend you copy the code in case you want to make some improvements. For each inherited form that you want to build, right-click on a project in the Solution Explorer and provide a name (usually the name of one of your data tables), then point to InheritedForm.dll (you may have to browse to it) and click on BaseForm . Fill in the MainTable , KeyField , and SearchField properties with the names of your main data table, key field, and the field you want users to search. Finally, drag text boxes and/or combo boxes onto the form and name them with three-letter prefixes denoting the control type (for example, txt , cmb , chk ) followed by the field names. Be sure to set the tab order using the View, Tab Order menu selection. (Hint: Click the same menu selection again when you're finished. That only took me an hour to discover.) Finally, disable all of the input fields. The user has to click on Add or Edit to change them. When you've finished your new form, add a menu selection for the table in your Main Form MainMenu control using the pattern described earlier in the chapter, and rebuild the project, and it oughta work. The Customer form shown in Figure 4.11 took me two minutes and 15 seconds to build, from start to finish. Figure 4.11. An Add/Edit/Delete form finished in less than three minutes. |
< Day Day Up > |