Back to Devexpress

How to: Bind a Spreadsheet to an MS SQL Server Database (Part 2)

windowsforms-117920-controls-and-libraries-spreadsheet-examples-data-binding-how-to-bind-a-spreadsheet-to-an-ms-sql-server-database-part-2.md

latest15.3 KB
Original Source

How to: Bind a Spreadsheet to an MS SQL Server Database (Part 2)

  • Oct 12, 2023
  • 9 minutes to read

This tutorial shows how to modify the data-bound spreadsheet application created in the How to: Bind a Spreadsheet to an MS SQL Server Database (Part 1) example to enable end-users to add, modify, and remove data in the connected data table.

Develop a User Interface

To provide the capability to interact with the database, add the following UI elements to the spreadsheet application created in the How to: Bind a Spreadsheet to an MS SQL Server Database (Part 1) example.

|

UI Element

|

Implementation

| | --- | --- | |

Data Entry Form

|

On the template worksheet, create a data entry form that will be used to insert new records into the database. For this, do the following.

  1. Unhide rows 3 through 10.

  2. Format the cell range “B3:J9” as shown in the following image, enter the field captions, and add the Save and Cancel cells.

  3. Hide rows 3 through 10 again.

| |

Ribbon Buttons

|

Create a new ribbon group and add the following buttons to it.

The table below contains the description of each button.

|

Caption

|

Name

|

Description

| | --- | --- | --- | |

Add Record

|

buttonAddRecord

|

Displays a data entry form on the template worksheet to add a new record to the Suppliers table.

| |

Remove Record

|

buttonRemoveRecord

|

Invokes the Delete dialog, which allows a user to remove the selected record from the database or cancel the delete operation.

| |

Apply Changes

|

buttonApplyChanges

|

Posts the updated data back to the database.

| |

Cancel Changes

|

buttonCancelChanges

|

Cancels the recent changes and loads the latest saved data from the data table.

|

|

Post Data to the Database

When you bind a control to a DataTable containing data from a database and then change data by adding, deleting or modifying records, these changes are accumulated in the DataTable but are not automatically posted to the underlying database. You have to manually call the Update method of the TableAdapter to propagate the modified data to the data source. Before calling this method, make sure that the appropriate INSERT , UPDATE , and DELETE SQL statements are specified for the data adapter. Otherwise, the Update method will generate an exception. For the SuppliersTableAdapter used in the current example, the required commands were generated automatically when the adapter was originally configured.

The table below describes how to add, modify, or delete data in the connected data source step by step.

|

Action

|

Implementation

| | --- | --- | |

Add a record

|

Important

The SpreadsheetControl does not support inserting rows at the end of a data-bound range, while a DataTable supports only this kind of operation.

To avoid this restriction, the current example uses a data entry form to add new records to the data source.

  1. Handle the Add Record button’s ItemClick event. Add code that displays the data entry form to the event handler.
  2. Handle the MouseClick event of the SpreadsheetControl to identify a cell that a user has currently clicked.

All changes made in the data source are immediately reflected in the bound worksheet.

| |

Apply changes

|

In the Apply Changes button’s ItemClick event handler, call the Update method of the SuppliersTableAdapter to save the modified data to the database.

| |

Cancel changes

|

Handle the Cancel Changes button’s ItemClick event.

In the event handler, close the cell’s in-place editor if it’s currently active and then call the Fill method of the SuppliersTableAdapter to load the latest saved data from the database.

| |

Remove a record

|

  1. Handle the Remove Record button’s ItemClick event. In the event handler, verify that the currently selected range belongs to the data-bound range.

  2. Handle the SpreadsheetControl.RowsRemoving event that fires before a row is deleted. Add code that displays the Delete confirmation dialog to the event handler.

  3. Handle the SpreadsheetControl.RowsRemoved event. This event occurs if a user confirmed the delete operation and the record was deleted. Call the SuppliersTableAdapter.Update method in the event handler to save changes to the database.

|

Code Sample

View Example

csharp
private void spreadsheetControl1_MouseClick(object sender, MouseEventArgs e) {
    Cell cell = spreadsheetControl1.GetCellFromPoint(e.Location);
    if (cell == null)
        return;
    Worksheet sheet = spreadsheetControl1.ActiveWorksheet;
    string cellReference = cell.GetReferenceA1();
    // If the "Save" cell is clicked in the data entry form, 
    // add a row containing the entered values to the database table.
    if (cellReference == "I4") {
        AddRow(sheet);
        HideDataEntryForm(sheet);
        ApplyChanges();
    }
    // If the "Cancel" cell is clicked in the data entry form, 
    // cancel adding new data and hide the data entry form.
    else if (cellReference == "I6") {
        HideDataEntryForm(sheet);
    }
}

void AddRow(Worksheet sheet) {
    try {
        // Append a new row to the "Suppliers" data table.
        dataSet.Suppliers.AddSuppliersRow(
            sheet["C4"].Value.TextValue, sheet["C6"].Value.TextValue, sheet["C8"].Value.TextValue,
            sheet["E4"].Value.TextValue, sheet["E6"].Value.TextValue, sheet["E8"].Value.TextValue,
            sheet.Cells["G4"].DisplayText, sheet.Cells["G6"].DisplayText);
    }
    catch (Exception ex) {
        string message = string.Format("Cannot add a row to a database table.\n{0}", ex.Message);
        MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

void HideDataEntryForm(Worksheet sheet) {
    CellRange range = sheet.Range.Parse("C4,C6,C8,E4,E6,E8,G4,G6");
    range.ClearContents();
    sheet.Rows.Hide(2, 9);
}

void ApplyChanges() {
    try {
        // Send the updated data back to the database.
        adapter.Update(dataSet.Suppliers);
    }
    catch (Exception ex) {
        string message = string.Format("Cannot update data in a database table.\n{0}", ex.Message);
        MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

private void spreadsheetControl1_RowsRemoving(object sender, RowsChangingEventArgs e) {
    Worksheet sheet = spreadsheetControl1.ActiveWorksheet;
    CellRange rowRange = sheet.Range.FromLTRB(0, e.StartIndex, 16383, e.StartIndex + e.Count - 1);
    CellRange boundRange = sheet.DataBindings[0].Range;
    // If the rows to be removed belong to the data-bound range,
    // display a dialog requesting the user to confirm the deletion of records. 
    if (boundRange.IsIntersecting(rowRange)) {
        DialogResult result = MessageBox.Show("Want to delete the selected supplier(s)?", "Delete", 
            MessageBoxButtons.YesNo, MessageBoxIcon.Question);
        applyChangesOnRowsRemoved = result == DialogResult.Yes;
        e.Cancel = result == DialogResult.No;
        return;
    }
}

private void spreadsheetControl1_RowsRemoved(object sender, RowsChangedEventArgs e) {
    if (applyChangesOnRowsRemoved) {
        applyChangesOnRowsRemoved = false;
        // Update data in the database.
        ApplyChanges();
    }
}

private void buttonAddRecord_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) {
    CloseInplaceEditor();
    Worksheet sheet = spreadsheetControl1.ActiveWorksheet;
    // Display the data entry form on the worksheet to add a new record to the "Suppliers" data table.
    if (!sheet.Rows[4].Visible)
        sheet.Rows.Unhide(2, 9);
    spreadsheetControl1.SelectedCell = sheet["C4"];
}

private void buttonRemoveRecord_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) {
    CloseInplaceEditor();
    Worksheet sheet = spreadsheetControl1.ActiveWorksheet;
    CellRange selectedRange = spreadsheetControl1.Selection;
    CellRange boundRange = sheet.DataBindings[0].Range;
    // Verify that the selected cell range belongs to the data-bound range.
    if (!boundRange.IsIntersecting(selectedRange) || selectedRange.TopRowIndex < boundRange.TopRowIndex) {
        MessageBox.Show("Select a record first!", "Remove Record", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    } 
    // Remove the topmost row of the selected cell range.
    sheet.Rows.Remove(selectedRange.TopRowIndex);
}

private void buttonApplyChanges_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) {
    CloseInplaceEditor();
    // Update data in the database.
    ApplyChanges();
}

private void buttonCancelChanges_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) {
    // Close the cell in-place editor if it's currently active. 
    CloseInplaceEditor();
    // Load the latest saved data into the "Suppliers" data table.
    adapter.Fill(dataSet.Suppliers);
}

void CloseInplaceEditor() {
    if (spreadsheetControl1.IsCellEditorActive)
        spreadsheetControl1.CloseCellEditor(DevExpress.XtraSpreadsheet.CellEditorEnterValueMode.Default);
}
vb
Private Sub spreadsheetControl1_MouseClick(ByVal sender As Object, ByVal e As MouseEventArgs) Handles spreadsheetControl1.MouseClick
    Dim cell As Cell = spreadsheetControl1.GetCellFromPoint(e.Location)
    If cell Is Nothing Then
        Return
    End If
    Dim sheet As Worksheet = spreadsheetControl1.ActiveWorksheet
    Dim cellReference As String = cell.GetReferenceA1()
    ' If the "Save" cell is clicked in the data entry form, 
    ' add a row containing the entered values to the database table.
    If cellReference = "I4" Then
        AddRow(sheet)
        HideDataEntryForm(sheet)
        ApplyChanges()
    ' If the "Cancel" cell is clicked in the data entry form, 
    ' cancel adding new data and hide the data entry form.
    ElseIf cellReference = "I6" Then
        HideDataEntryForm(sheet)
    End If
End Sub

Private Sub AddRow(ByVal sheet As Worksheet)
    Try
        ' Append a new row to the "Suppliers" data table.
        dataSet.Suppliers.AddSuppliersRow(sheet("C4").Value.TextValue, sheet("C6").Value.TextValue, sheet("C8").Value.TextValue, sheet("E4").Value.TextValue, sheet("E6").Value.TextValue, sheet("E8").Value.TextValue, sheet.Cells("G4").DisplayText, sheet.Cells("G6").DisplayText)
    Catch ex As Exception
        Dim message As String = String.Format("Cannot add a row to a database table." & ControlChars.Lf & "{0}", ex.Message)
        MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try
End Sub

Private Sub HideDataEntryForm(ByVal sheet As Worksheet)
    Dim range As CellRange = sheet.Range.Parse("C4,C6,C8,E4,E6,E8,G4,G6")
    range.ClearContents()
    sheet.Rows.Hide(2, 9)
End Sub

Private Sub ApplyChanges()
    Try
        ' Send the updated data back to the database.
        adapter.Update(dataSet.Suppliers)
    Catch ex As Exception
        Dim message As String = String.Format("Cannot update data in a database table." & ControlChars.Lf & "{0}", ex.Message)
        MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try
End Sub

Private Sub spreadsheetControl1_RowsRemoving(ByVal sender As Object, ByVal e As RowsChangingEventArgs) Handles spreadsheetControl1.RowsRemoving
    Dim sheet As Worksheet = spreadsheetControl1.ActiveWorksheet
    Dim rowRange As CellRange = sheet.Range.FromLTRB(0, e.StartIndex, 16383, e.StartIndex + e.Count - 1)
    Dim boundRange As CellRange = sheet.DataBindings(0).Range
    ' If the rows to be removed belong to the data-bound range,
    ' display a dialog requesting the user to confirm the deletion of records. 
    If boundRange.IsIntersecting(rowRange) Then
        Dim result As DialogResult = MessageBox.Show("Want to delete the selected supplier(s)?", "Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
        applyChangesOnRowsRemoved = result = DialogResult.Yes
        e.Cancel = result = DialogResult.No
        Return
    End If
End Sub

Private Sub spreadsheetControl1_RowsRemoved(ByVal sender As Object, ByVal e As RowsChangedEventArgs) Handles spreadsheetControl1.RowsRemoved
    If applyChangesOnRowsRemoved Then
        applyChangesOnRowsRemoved = False
        ' Update data in the database.
        ApplyChanges()
    End If
End Sub

Private Sub buttonAddRecord_ItemClick(ByVal sender As Object, ByVal e As DevExpress.XtraBars.ItemClickEventArgs) Handles buttonAddRecord.ItemClick
    CloseInplaceEditor()
    Dim sheet As Worksheet = spreadsheetControl1.ActiveWorksheet
    ' Display the data entry form on the worksheet to add a new record to the "Suppliers" data table.
    If Not sheet.Rows(4).Visible Then
        sheet.Rows.Unhide(2, 9)
    End If
    spreadsheetControl1.SelectedCell = sheet("C4")
End Sub

Private Sub buttonRemoveRecord_ItemClick(ByVal sender As Object, ByVal e As DevExpress.XtraBars.ItemClickEventArgs) Handles buttonRemoveRecord.ItemClick
    CloseInplaceEditor()
    Dim sheet As Worksheet = spreadsheetControl1.ActiveWorksheet
    Dim selectedRange As CellRange = spreadsheetControl1.Selection
    Dim boundRange As CellRange = sheet.DataBindings(0).Range
    ' Verify that the selected cell range belongs to the data-bound range.
    If (Not boundRange.IsIntersecting(selectedRange)) OrElse selectedRange.TopRowIndex < boundRange.TopRowIndex Then
        MessageBox.Show("Select a record first!", "Remove Record", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Return
    End If
    ' Remove the topmost row of the selected cell range.
    sheet.Rows.Remove(selectedRange.TopRowIndex)
End Sub

Private Sub buttonApplyChanges_ItemClick(ByVal sender As Object, ByVal e As DevExpress.XtraBars.ItemClickEventArgs) Handles buttonApplyChanges.ItemClick
    CloseInplaceEditor()
    ' Update data in the database.
    ApplyChanges()
End Sub

Private Sub buttonCancelChanges_ItemClick(ByVal sender As Object, ByVal e As DevExpress.XtraBars.ItemClickEventArgs) Handles buttonCancelChanges.ItemClick
    ' Close the cell in-place editor if it's currently active. 
    CloseInplaceEditor()
    ' Load the latest saved data into the "Suppliers" data table.
    adapter.Fill(dataSet.Suppliers)
End Sub

Private Sub CloseInplaceEditor()
    If spreadsheetControl1.IsCellEditorActive Then
        spreadsheetControl1.CloseCellEditor(DevExpress.XtraSpreadsheet.CellEditorEnterValueMode.Default)
    End If
End Sub