4.1 Edit Data and Update Changes That Are Made to an ADO.NET DataSet Object

Listing and viewing data is easy. What you really need to do is to be able to edit and update data. You know you can use the DataSet object and some of its objects and methods to perform this task. How do you edit and update data using the DataSet object?

Technique

In this How-To, you will use the DataAdapter, DataSet, DataTable, and DataRow objects. You have experienced some of the properties and methods of each of these objects before. In this chapter, you are going to be using the following properties and methods that are shown in Table 4.1.

Table 4.1. DataAdapter, DataSet, DataTable, and DataRow Properties and Methods

Object /Method

Property

Description

DataAdapter

Fill

Fills DataSet and DataTable objects.

CommandBuilder

GetUpdateCommand

Creates an Update command and places it into the data adapter's UpdateCommand property.

DataAdapter

UpdateCommand

Holds the SQL statement for the update.

DataAdapter

Close

Closes the connection off the UpdateCommand. The syntax is dataadapter.UpdateCommand.Connect.Close().

DataAdapter

Update

Performs the update command against the dataset.

DataSet

Tables

Represents a collection of tables found within a dataset.

DataSet

Rows

Contains a collection of rows within a specified table in a dataset.

DataSet

AcceptChanges

Sends the changes back to the server.

DataRow

ToString

Retrieves the data from the column that is specified in the DataRow and returns it as a string value.

DataRow

BeginEdit

Begins the editing of a DataRow, allowing you to replace values in the columns.

DataRow

EndEdit

Completes the editing of a DataRow.

You will see these objects with their properties and methods used in the following steps.

Steps

Open and run the VB.NET-Chapter 4 solution. From the main form, click on the command button with the caption How-To 4.1. When the form loads, click on the Load List button to display the customers that begin with the letter A. Click the Edit button. You will notice that the fields have now taken on a sunken look. Place the cursor into the City field and change the value to Dunkirk. Now click Save. If you move off the record and move back on, you will notice that the value has been saved.

This form looks similar to the form created in Chapter 1. The difference is that this time you will not be using controls that are bound at design time. You can see the form in Figure 4.1.

  1. Create a new Windows Form.

  2. Add the following controls, setting the properties as listed in Table 4.2.

    Table 4.2. Controls Property Settings

    Object

    Property

    Setting

    Label

    Name

    Caption

    Label1

    Customer

    TextBox

    Name

    Text

    txtCustLimit

    A

    Button

    Name

    Caption

    btnLoadList

    Load List

    ListBox

    Name

    lstCustomers

    Label

    Caption

    Customer ID

    Label

    Caption

    Company Name

    Label

    Caption

    Contact

    Label

    Caption

    Contact Title

    Label

    Caption

    Address

    Label

    Caption

    City

    Label

    Caption

    Region

    Label

    Caption

    Country

    Label

    Caption

    Phone

    Label

    Caption

    Fax

    TextBox

    Name

    txtCustomerID

    TextBox

    Name

    txtCompanyName

    TextBox

    Name

    txtContact

    TextBox

    Name

    txtContactTitle

    TextBox

    Name

    txtAddress

    TextBox

    Name

    txtCity

    TextBox

    Name

    txtRegion

    TextBox

    Name

    txtPostalCode

    TextBox

    Name

    txtCountry

    TextBox

    Name

    txtPhone

    TextBox

    Name

    txtFax

    Button

    Name

    Caption

    btnEdit

    &Edit

    Button

    Name

    Caption

    btnSave

    &Save

    Button

    Name

    Caption

    btnCancel

    &Cancel

    Note

    graphics/note_icon.gif

    Notice that the Text property of the text boxes is not being set at design time. In Chapter 1, "Developing Windows Forms Using Bound Controls," they were set to columns of a dataset that was included on the form. In this How-To, they will be set at run-time.

  3. In the class module for the form, add the following three Private declarations just below the line of code that reads Windows Form Designer generated code. These three objects will be used throughout the form.

    Dim mdsCustIndiv As New DataSet()
    Dim modaCustIndiv As OleDb.OleDbDataAdapter
    Dim mdrCustIndiv As DataRow
    
  4. Enter the following code as the Click event for btnLoadList:

    Private Sub btnLoadList_Click(ByVal sender As System.Object, _
                  ByVal e As System.EventArgs) Handles btnLoadList.Click
    
            '-- Move the loading of the list to a subroutine for
            '   additional(calls)
            LoadList()
    
        End Sub
    
  5. Create the LoadList routine by entering the following code into the form you created for this How-To. This code creates and fills a data table using a data adapter. The string that the data adapter uses creates a Select statement by using the txtCustLimit text box. The DataSource, DisplayMember, and ValueMember properties of the list box are then bound. Last, the LoadIndividual routine is called, which is described in the next step.

    Private Sub LoadList()
    
            Dim odaCustList As OleDb.OleDbDataAdapter
            Dim dtCustList As DataTable = New DataTable()
    
            Dim strSQL As String
    
            '-- Create the SQL String
            strSQL = "Select CustomerID, CompanyName " & _
                        From Customers Where CustomerID Like '" & _
                        Me.txtCustLimit.Text & "%'"
    
    
            '-- Set up the exception catch
            Try
    
                '-- Create an instance of the data adapter; then fill the data              
    graphics/ccc.giftable
                odaCustList = New OleDb.OleDbDataAdapter(strSQL, _
                        BuildCnnStr("(local)", "Northwind"))
                odaCustList.Fill(dtCustList)
    
                '-- Bind the data to the list box
                lstCustomers.DataSource = dtCustList
                lstCustomers.DisplayMember = "CompanyName"
                lstCustomers.ValueMember = "CustomerID"
    
            LoadIndividual()
            Catch oexpData As OleDb.OleDbException
                MsgBox(oexpData.Message)
            End Try
    
        End Sub
    
  6. Create the LoadIndividual routine by entering the following code in the form you created for this How-To. Taking the SelectedItem from the list box, a data adapter is created, and a dataset is filled. Next, the individual DataRow is created. Last, each of the TextBox controls is loaded with the value from the column with the corresponding name. Notice the use of the Try-Catch-End-Try to ignore controls that don't have a like column in the DataRow.

    Private Sub LoadIndividual()
    
            Dim strSQL As String
            Dim strName As String
            Dim oCtl As Object
    
            mdsCustIndiv.Clear()
    
            If Me.lstCustomers.SelectedIndex <> -1 Then
    
                Try
                    '-- Load the individual record into the dataset
                    strSQL = "Select * from Customers Where CustomerID = '" &
                                      Me.lstCustomers.SelectedItem(0) & "'"
                    modaCustIndiv = New OleDb.OleDbDataAdapter(strSQL, _
                                      BuildCnnStr("(local)", "Northwind"))
    
                    '-- Fill the dataset
                    modaCustIndiv.Fill(mdsCustIndiv, "Customers")
    
                    '-- Grab the individual data row
                    mdrCustIndiv = mdsCustIndiv.Tables("Customers").Rows(0)
    
                Catch oexpData As OleDb.OleDbException
    
                    MessageBox.Show("Error loading individual data: " _
                                       & oexpData.Message)
                    Exit Sub
    
                End Try
    
                '-- Run through the text boxes on the form, and
                '-- if they match up with a field from the record,
                 '  load them.
    
                For Each oCtl In Me.Controls
    
                    If TypeOf oCtl Is TextBox Then
    
                        strName = Mid(oCtl.Name, 4)
    
                        '-- By trapping the exception this way, errors are ignored.
                        Try
                            oCtl.text = mdrCustIndiv(strName).ToString
                        Catch oexp As Exception
                        End Try
    
                    End If
    
                Next
    
            End If
        End Sub
    
  7. Enter the following code to the Click event for lstCustomers:

    Private Sub lstCustomers_Click(ByVal sender As Object,
                    ByVal e As System.EventArgs) Handles lstCustomers.Click
    
            '-- Fill the current list item's individual dataset
            LoadIndividual()
    
    End Sub
    
  8. Enter the following code to the Click event for btnEdit:

    Private Sub btnEdit_Click(ByVal sender As System.Object,
                          ByVal e As System.EventArgs) Handles btnEdit.Click
    
            '-- Enable the editing of the form
            ActivateEditing(True)
    
    End Sub
    
  9. Create the ActivateEditing routine by entering the following code in the form you created for this How-To. Introduced in Chapter 1, this code goes through each of controls on the form, looking for text boxes, then setting the BorderStyle and BackColor properties based on whether the controls are to be enabled or disabled. The Enabled property of each control is then set as well.

    Private Sub ActivateEditing(ByVal bEnable As Boolean)
    
    
            Dim oCurr As Object
    
            '-- Loop through each of the controls on the form
            For Each oCurr In Me.Controls()
    
                '-- Check to see if the control is a text box
                If TypeOf oCurr Is TextBox And oCurr.Name <> "txtCustLimit" Then
    
                    '-- If so, toggle the properties
                    If bEnable Then
    
                        oCurr.BorderStyle() = _
                                System.Windows.Forms.BorderStyle.Fixed3D
    
                        oCurr.BackColor() = System.Drawing.Color.White
    
                    Else
    
                        oCurr.BorderStyle() = _
                                System.Windows.Forms.BorderStyle.FixedSingle
    
                        oCurr.BackColor() = Me.BackColor
    
    
                    End If
    
                    oCurr.Enabled = bEnable
    
                End If
            Next
    
    End Sub
    
  10. Enter the following code to the Click event btnSave:

    Private Sub btnSave_Click(ByVal sender As System.Object, _
                          ByVal e As System.EventArgs) Handles btnSave.Click
    
            '-- Save the information
            SaveRecord()
    
            '-- Disable the text boxes
            ActivateEditing(False)
    
        End Sub
    
  11. Create the SaveRecord routine by entering the following code in the form that you created for this How-To. Using a DataRow object, the BeginEdit method is called, and then each of the controls is stored back into the columns of the same names, if they exist. The EndEdit method is then called to complete the editing of the DataRow. A CommandBuilder object is created to create the Update command for the DataAdapter object. The DataAdapter Update method is called to update the dataset with the data changed and then the AcceptChanges of the DataSet object. This accepts all the changes for all the objects and posts the data back to the server. Finally, the connection is closed for the UpdateCommand of the DataAdapter object.

    Private Sub SaveRecord()
    
            Dim oCtl As Object
            Dim strName As String
    
            '-- Start the editing in the datarow.
            mdrCustIndiv.BeginEdit()
    
            '-- Run through the text boxes on the form, and
            '-- if they match up with a field from the record,
            '-- place the value back in the record.
            For Each oCtl In Me.Controls
    
                If TypeOf oCtl Is TextBox Then
    
                    strName = Mid(oCtl.Name, 4)
    
                    '-- By trapping the exception this way, errors are ignored.
                    Try
                        mdrCustIndiv(strName) = oCtl.text
                    Catch oexp As Exception
                    End Try
    
                End If
    
            Next
    
            '-- Finish the editing of the data row
            mdrCustIndiv.EndEdit()
    
            Try
    
                '-- Create an instance of the command builder
                Dim ocbCustIndiv As OleDb.OleDbCommandBuilder
                ocbCustIndiv = New OleDb.OleDbCommandBuilder(modaCustIndiv)
    
                '-- Have the command builder create an update SQL command
                modaCustIndiv.UpdateCommand = ocbCustIndiv.GetUpdateCommand
    
                '-- Perform the update SQL command; then close the connection
                modaCustIndiv.Update(mdsCustIndiv, "Customers")
                mdsCustIndiv.Tables("Customers").AcceptChanges()
                modaCustIndiv.UpdateCommand.Connection.Close()
    
    
            Catch excData As Exception
    
            End Try
    
        End Sub
    
  12. Enter the following code to the Click event btnCancel:

    Private Sub btnCancel_Click(ByVal sender As System.Object, _
                       ByVal e As System.EventArgs) Handles btnCancel.Click
    
            '-- Use the BindingContext class to cancel the current editing.
        LoadIndividual()
         ActivateEditing(False)
    
    End Sub
    
Figure 4.1. Although this looks like the form created in Chapter 1, you have more control over this version with unbound controls.

graphics/04fig01.jpg

How It Works

When the user clicks on the btnLoadList Button, the lstCustomers list box is loaded via the odaCustList data adapter and dtCustList data table. The first customer's information is then loaded in the text boxes on the right side of the form. When the btnEdit button is clicked, the look of the text boxes is changed to sunken, and they are enabled for editing of the text. After changing the data, when the user clicks on the btnSave button, the data is then stored back into the server, and the text boxes are changed to disabled. If the btnCancel is clicked, the text boxes are changed to disabled.

Comments

Although it takes a bit more code to handle the editing and updating of data with unbound controls versus bound controls, you might like it better because you can control the code. With bound controls, the code is written for you. The code that is displayed here can be modified to be more generic so that you don't have to write individual routines for each form.