Saving Changed Data
You've now created a data entry form, but haven't provided the application with the ability to update the database. The DataWindow won't save changes until you add a little more code. The following try...catch
block commits the data only if the user's changes are valid. Before saving, the code calls the AcceptText()
method, which captures all pending changes if users have not moved the cursor off the last column they changed.
Adding New Rows
//get all changes pending in the buffer if the user
//has not tabbed away from the last column changed
//try to update
//commit the changes
catch (Sybase.DataWindow.DbErrorException ex)
"Changes Not Saved",
"Database Error Encountered");
catch (Exception ex)
"Unexpected Error Encountered");
You add new rows to the DataWindow by calling the InsertRow()
method. Supply 0
as the argument to add the row at the bottom, or supply a number less than the total number of rows to insert a blank row between existing rows. After inserting the new row, you will probably want to scroll to the row. You could highlight the row, but for now, just let the user click in the row and start entering data. Add the following code to the ButtonAdd_Click
//add a row to end (0=add to end)
//get the count of rows and go
//to the last row.
Here's some quick code to delete a row when a user clicks in a row and then clicks the Delete button. This sample simply displays the deleted row, but ideally, you'd present a warning message with better information before issuing the DeleteRow()
method. Remember, the DataWindow doesn't physically delete the row from the database unless the user clicks Save. Until that point, delete, add, and edit changes occur only in a buffer area. Add the following code to the ButtonDelete_Click
One Finishing TouchClosing the DataWindow Form
// buttonDelete code
//delete the current row
nRow = dwc1.CurrentRow;
//make sure the user has made a row active by
//selecting one with the mouse
if (nRow > 0)
"Deleted a row");
Before letting users close the form, you'll want to detect whether they have pending changes (inserts, deletes, edits) that have not been saved. The following code checks for unsaved changes, and when found displays a dialog that provides a warning, but still lets users elect to exit without saving changes. Add the following code to the ButtonClose_Click
Object-Oriented Design and More
nRows = dwc1.ModifiedCount + dwc1.DeletedCount;
if (nRows > 0)
MessageBox.Show("Save your changes or exit " +
"via the window menu",nRows.ToString() +
" Pending changes not saved");
For some final thoughts, it's worth noting that the code you placed on the form is independent of any DataWindow object that you might place on the window. Because the DataWindow separates data access and data interaction from the control, the DataWindow control works with any DataWindow object. To prove this, you'll modify the FirstDataWindow
project by adding code that lets you select the DataWindow object that the control uses. Use the dropdown list at the top to select from three different DataWindows, and then click the Retrieve button. You don't have to change a single line of code to get all the functionality of the buttons.
Create two new DataWindows using the DataWindow Designer. Create one DataWindow object named de_stores
that accesses the stores
table. Create another DataWindow object named dw_sales
. Now go back to Visual Studio and add a ComboBox control to the form. Name the object comboBox1
. Set the Items property to "Collection". Click the ellipse button, and then enter the following four lines in the string collection editor:
Change the code for the buttonRetrieve
control so it dynamically changes the DataWindow object based on the combo box selection.
sDatawindowObject = comboBox1.Text;
if (sDatawindowObject.Length <= 3)
// set to de_authors if somehow the user did not
// select one of the 3 valid datawindows
sDatawindowObject = "de_authors";
// tell the datawindow what transation to use along
// with the dataobject
dw1.DataWindowObject = sDatawindowObject;
//dynamically change the datawindow
You'll be surprised at the results.
This article has barely scratched the surface of the DataWindow's capabilities as either a user interface control or as a data access control. You can see the query generated when the DataWindow talks to the database by adding the following code to the DataWindow control. Each call to the database (SELECT
) triggers the SqlPreview
event. Select the DataWindow control and click the events list to add this event. You'll see question marks in place of the data unless you change the BindVariable
There's simply not enough space in this article to cover more advanced topics, such as:
- Master-detail windows
- Drilldown capabilities
- Dynamic controls
- Controlling properties using code
- Datastores (non visual DataWindows)
- Deployment capabilities
DropdownDataWindows are extremely important when a column in one table relies on a column in another table. In essence, you nest one or more DataWindows within a main DataWindow object to achieve master-detail capability. For example, you can achieve the functionality of embedding a ComboBox within a DataGrid column via the DataWindow with no coding. Set the Edit
property to DropDownDW
and select the DataWindow you want to use as the dropdown. The sample source code contains two DropdownDataWindows attached to the DataWindow de_titlesauthors
shows the result of clicking one of the dropdown arrows on a DataWindow containing several DropDownDataWindows.
Figure 27. Embedding a DropDown DataWindow in a Column: Embedding a dropdown list in a column requires no code.
Figure 28. DataWindow with Embedded Dropdowns: The figure shows the result of clicking a dropdown arrow in a DataWindow containing several DropDownDataWindows.
You've seen the most basic DataWindow capabilities, and it should be clear that you can use the DataWindow control to create a form that accesses any database, lets users issue their own queries and return the data in a grid, complete with sort, filter, print, and export functionalityall in fewer than fifty lines of code.