SlideShare a Scribd company logo
Database Programming With Visual Basic Net And
Adonet Tips Tutorials And Code 1st Edition
Barker download
https://ebookbell.com/product/database-programming-with-visual-
basic-net-and-adonet-tips-tutorials-and-code-1st-edition-
barker-55142012
Explore and download more ebooks at ebookbell.com
Here are some recommended products that we believe you will be
interested in. You can click the link to download.
Oracle Database Programming With Visual Basicnet Concepts Designs And
Implementations Ying Bai
https://ebookbell.com/product/oracle-database-programming-with-visual-
basicnet-concepts-designs-and-implementations-ying-bai-29341140
Sql Server Database Programming With Visual Basicnet Concepts Designs
And Implementations 1 Ying Bai
https://ebookbell.com/product/sql-server-database-programming-with-
visual-basicnet-concepts-designs-and-implementations-1-ying-
bai-11137566
A Guide To The Practical Issues And Applications In Database
Programming With Updated Visual Basicnet Murillo
https://ebookbell.com/product/a-guide-to-the-practical-issues-and-
applications-in-database-programming-with-updated-visual-basicnet-
murillo-44123730
Practical Database Programming With Visual Basicnet 2nd Edition 2nd
Edition Ying Bai
https://ebookbell.com/product/practical-database-programming-with-
visual-basicnet-2nd-edition-2nd-edition-ying-bai-36180040
Practical Database Programming With Visual Basicnet Ying Bai
https://ebookbell.com/product/practical-database-programming-with-
visual-basicnet-ying-bai-4105898
Practical Database Programming With Visual Basicnet 1st Edition Ying
Bai
https://ebookbell.com/product/practical-database-programming-with-
visual-basicnet-1st-edition-ying-bai-1367072
Practical Database Programming With Visual Cnet Ying Bai
https://ebookbell.com/product/practical-database-programming-with-
visual-cnet-ying-bai-47700374
Database Programming With Vbnet Carsten Thomsen Mcse Mcsd Microsoft
Mvp Auth
https://ebookbell.com/product/database-programming-with-vbnet-carsten-
thomsen-mcse-mcsd-microsoft-mvp-auth-4592406
Database Programming With C 1st Edition Carsten Thomsen Auth
https://ebookbell.com/product/database-programming-with-c-1st-edition-
carsten-thomsen-auth-11852272
Database Programming With Visual Basic Net And Adonet Tips Tutorials And Code 1st Edition Barker
1
1.1 Create a Bound List Box 1
1.2 Limit the Data Displayed in a Bound List Box 9
1.3 Bind and View Individual Text Boxes Based Off a Selected List Box Item 13
1.4 Edit and Update Data Using Bound Controls 21
1.5 Add and Delete Records Using Bound Controls 27
1.6 Take Care of Error Handling with Bound Controls 32
1.7 Put the Finishing Touches on a Data Bound Form 37
1.8 Bind Data to ComboBox and DataGrid Controls 42
1.9 Drill Down to Data in the DataGrid Control 46
10.1 Create a Report Using Crystal Reports Report Expert 54
10.2 Display a Report That Was Created 64
10.3 Add Calculated Fields to the Crystal Reports Report 70
10.4 Select Whether the Report Will Be Displayed, Printed, or Exported Using Visual Basic .NET Code 73
10.5 Determine Which Records Will Be Printed at Runtime 80
10.6 Print Labels and Control the Order in Which Records Will Be Printed 85
10.7 Create an Onscreen Report That Contains Hyperlinks 90
11.1 Create Windows NT/2000 Users 94
11.10 Use Object Permissions 99
11.11 Use Fixed Database Roles 102
11.12 Create Custom Database Roles 106
11.13 Create Application Roles 109
11.2 Create Windows NT/2000 Groups 111
11.3 Establish a Windows NT/2000 Authentication Mode 114
11.4 Establish Mixed-Mode Authentication 118
11.5 Create a Standard Login 120
11.6 Create a Windows NT/2000 Login 123
11.7 Use a Fixed Server Role 125
11.8 Create a Database User Account 129
11.9 Use Statement Permissions 132
12.1 Use XMLWriter to Create an XML Document 135
12.2 Use XMLReader to Read an XML Document 143
12.3 Work with the XML Document Object Model 147
12.4 Retrieve XML from SQL Server 2000 154
12.5 Work with Datasets and XML 159
13.1 Get Started with XML Web Services 164
13.2 Create a Simple XML Web Service Using Parameters 172
13.3 Consume XML Web Services 177
13.4 Pass a Dataset Back from an XML Web Service 181
2
2.1 Create a New SQL Server Database from Within Visual Studio .NET 186
2.2 Define Tables and Fields 188
2.3 Define a Primary Key and Other Indexes 193
2.4 Define Relations Between Tables 197
2.5 Define Defaults and Constraints 202
2.6 Create Views 205
2.7 Create Stored Procedures 209
3
3.1 Retrieve Data by Using the DataReader Object 212
3.2 Retrieve Results from SQL Server by Using the DataTable Object 217
3.3 Locate Records with the DataTable Object 219
3.4 Filter and Sort Records Using the DataView Object 223
4
4.1 Edit Data and Update Changes That Are Made to an ADO.NET DataSet Object 229
4.2 Add and Delete Rows in a Dataset with ADO.NET 241
4.3 Execute Parameterized Stored Procedures in ADO.NET 246
4.4 Create and Execute On-the-Fly Batch Updates by Using ADO.NET 249
5
5.1 Use Bound Controls with Web Forms 253
5.2 Validate Data Using Validation Controls 263
5.3 Populate DropDown and ListBox Controls 269
5.4 Display Data Using the Table Control 276
5.5 Display Data Using the Repeater Control 281
5.6 Display, Sort, and Page Data in the DataGrid Control 289
5.7 Add, Edit, and Delete Data Using the DataGrid Control 295
5.8 Hyperlink from a Row in the Data Grid to a Detail Page 306
6
6.1 Retrieve Unique Records Using Only a Select Query 311
6.2 Use Variables and Functions in T-SQL 317
6.3 Use Wildcards and Ranges of Values in a SQL Query 321
6.4 Find Records in a Table Without Corresponding Entries in a Related Table 327
6.5 Take Advantage of Using Subqueries 331
6.6 Create, Modify, and Delete Tables 335
6.7 Create a New Table with Data from Existing Tables 342
6.8 Create and Call SQL Server 2000 User-Defined Functions 346
7
7.1 Create a Dialog Box to Connect to a New Database, Including Listing Available SQL Servers and
Databases
353
7.2 Back Up and Verify a SQL Server Database 362
7.3 Restore a SQL Server Database 371
7.4 Transfer Tables Between SQL Server Databases 376
7.5 Create a Detach/Attach SQL Server Database Dialog Box 386
8
8.1 Work with Data-Bound Multi-Select List Boxes Using Windows Forms 394
8.2 Use a Single Windows Form to Update Multiple Lookup Tables 403
8.3 Create a Point-and-Click SQL Server Query Tool for Users Using a Windows Form 409
8.4 Make a Generic Search Form in a Visual Basic .NET Desktop Application 417
8.5 Work with Data-Bound Multi-Select List Boxes Using Web Forms 428
8.6 Use a Single Web Form to Update Multiple Lookup Tables 438
8.7 Create a Point-and-Click Query Tool for Users Using a Web Form 454
8.8 Make a Generic Search Form in an ASP.NET Web Application 462
9
9.1 Define a Class in Visual Basic .NET 472
9.2 Create a Class That Implements the Interface You Defined 478
9.3 Use Visual Studio .NET Tools to Speed Up Writing ADO.NET Code 486
9.4 Control the Creation and Behavior of Classes 499
9.5 Implement the Methods That Update the Database 505
9.6 Validate Data Passed to Properties and Communicate Errors to Developers 514
9.7 Write Data Validation Code That Can Be Reused in Other Classes 520
A
About the Author 533
Acknowledgments 534
Appendix A. Desktop Development With ADO 535
C
Chapter 1. Developing Windows Forms Using Bound Controls 536
Chapter 10. Creating Reports Using Crystal Reports 537
Chapter 11. Managing SQL Server Security 538
Chapter 12. Utilizing XML Data In Your Visual Basic .NET Applications 539
Chapter 13. Creating XML Web Services 540
Chapter 2. Creating SQL Server Database Objects From Visual Studio .NET 542
Chapter 3. Viewing Data With ADO.NET 543
Chapter 4. Manipulating Data With ADO.NET 544
Chapter 5. Working With Data In Web Forms 545
Chapter 6. Creating Transact-SQL Commands 546
Chapter 7. Performing Common Database Tasks Using SQL-DMO 547
Chapter 8. Taking Advantage of Data-Driven Techniques 550
Chapter 9. Using Classes With Databases to Make Life Easier 553
Comments 554
Conclusion 555
Copyright 556
Creating SQL Server Objects with ActiveX Data Objects 558
D
Dealing with Stateless Programming 560
Differences Between ADO and ADO.NET 563
E
Executing a SQL Server Stored Procedure By Using ActiveX Data Objects 564
Executing Batch Updates with ADO and SQL Server 566
I
Index 568
Index A 569
Index B 573
Index C 581
Index D 608
Index E 622
Index F 625
Index G 633
Index H 634
Index I 636
Index J 638
Index K 639
Index L 640
Index M 645
Index N 649
Index O 651
Index P 657
Index Q 665
Index R 666
Index S 675
IndexSYMBOL 687
Index T 688
Index U 694
Index V 696
Index W 700
Index X 706
Introduction 709
L
Looking At the ADO Object Models 710
Looking at the SQL Server DMF APIs 712
M
Main Page 714
O
Objects That Are Found in ADO.NET 715
Overview of the XML Web Services Infrastructure 719
R
Referencing the Type Libraries 721
S
Setting References in .NET for the SQL APIs 723
T
Table of content 724
Tell Us What You Think! 728
U
Using the 'Connection' Object 729
Utilizing Properties for Tables and Columns 732
W
Ways of Utilizing XML in .NET 734
What's Covered in 'Database Programming with Visual Basic .NET and ADO.NET: Tips, Tutorials, and
Code'?
735
When to Use ADO (Local Database/Single Tier Applications) 737
Who Is This Book For? 738
Working with Tables, Columns, and Rows 739
Working with the ADO 'Recordset' Object 740
X
XML Namespaces in .NET 744
[ Team LiB ]
1.1 Create a Bound List Box
It used to be that when you wanted to create a data entry form, you just assigned a recordset to the data
control and allowed the users to scroll through the data, making changes as needed. When you're dealing
with Client Server or Web applications, this just doesn't cut it.
One of the first things you need to do is provide a method to limit the amount of data so that users can pick
which record they want to edit/view, without pulling all the fields of a table over the Net—either LAN or
Internet. List boxes and combo boxes help with that. In this How-To, you will learn how to set up two data
controls: OleDbDataAdapter and DataSet. These controls enable you to populate a list box with one line
of code.
You want to see a list of customers on your Windows form in a ListBox control. You don't want to write
code at this point. You only want to prototype a form, so you just want to use bound data controls. How do
you create a list box and bind it using the data controls?
Technique
To get started with learning about any of the objects used for data in .NET, it's important to talk about what
.NET Namespaces are and how to use them.
Using .NET Namespaces
The .NET Framework contains a big class library. This class library consists of a number of Namespaces.
These Namespaces are made up of various classes that allow us to create our objects. All of the objects and
classes that make up the .NET objects, such as forms, controls, and the various data objects, can be found
in Namespaces.
Namespaces also can be made up of other Namespaces. For example, there is a Namespace called
System.Data. Although this Namespace has classes in it, such as DataSet and DataTable, it also has
Namespaces within it called System.Data.OleDb and System.Data.SQLClient, as well as others. To
check out the .NET Namespaces, choose Object Browser from the View menu. You can then expand the
System.Data Namespace to see the other Namespaces contained within.
If you are positive that the database you are going to be working with is SQL Server, then you would be far
better served performance-wise to use the classes found in the System.Data.SQLClient Namespace.
However, if you are not sure what database you will be working against, you should use the classes found in
System.Data.OleDb.
For this book, I am using objects created from the classes in the System.Data.OleDb Namespace. That
way, you can use the routines against other databases with less modifications.
Tip
If you know that the back end that you will be accessing is SQL
Server, then use the SQL Server type data controls because they are
optimized for it.
Eight data controls are available for Windows forms. Table 1.1 lists these controls and their uses. You can
find these controls by clicking on the Data group in the toolbox.
Table 1.1. Data Controls Used in Windows Forms
Control Name Purpose
DataSet This control is used in conjunction with the other data controls, storing the results that
are returned by commands and the DataAdapters. Unlike the recordset from ADO
and DAO, the DataSet actually brings back a hierarchical view of the data. Using
properties and collections in the DataSet object, you can get all the way down to
individual tables, rows, and columns.
OleDbDataAdapter This control stores and manages the commands you want to use against an OleDb
provider such as Jet, Oracle, or SQL Server. The commands for selecting, updating,
inserting, and deleting records can be used. The Connection against which to use the
commands is also tracked.
OleDbConnection This control maintains connection information for an OleDb provider. This control is
used with the OleDbDataAdapter.
OleDbCommand Similar to the ADO command object, this control allows you to execute SQL
statements or stored procedures to either run bulk operations or return data.
SqlDataAdapter This control is the same as the OleDbDataAdapter except that it is for use only
against SQL Server stores.
SqlConnection This control is the same as the OleDbConnection except that it is for use only
against SQL Server stores.
SqlCommand This control is the same as the OleDbCommand except that it is for use only against
SQL Server stores.
DataView This control creates multiple views of the same table. This includes looking at data in
various states such as deleted, changed, or sorted differently.
Creating two types of the data controls just mentioned, OleDbDataAdapter and DataSet, bind them to a
list box to display a list of customers. Note that an OleDbConnection control is also created, but Visual
Studio .NET creates it. You then add a line of code to fill the dataset.
Steps
To preview this How-To, open the solution called VB.Net—Chapter1 found in the chapter folder. When you
run the project, the first form that comes up is the main switchboard with each of the How-Tos listed for this
chapter. Click on How-To 1.1 to open the form for How-To 1.1 (see Figure 1.1).
Figure 1.1. Main form and How-To form 1.1 from the first chapter's solution.
Note
You can find the source code for all the chapters in the book at
www.samspublishing.com. After you are there, just type the book
ISBN (0672322471).
Create a new Visual Studio .NET project using the Windows Application project template. This creates
the initial form called Form1 that you will use.
1.
Drag the OleDbDataAdapter control from the Data Controls group located in the toolbox and drop it
onto the form. The Data Adapter Configuration Wizard appears. Read the introductory screen, and then
click Next to choose your data connection. At this point, if you don't see a data connection to
Northwind database in the drop-down list of data connections to use, click the New Connection button.
You then see the Data Link Properties dialog box with which you are familiar if you have used other
Microsoft products such as Visual Studio 6.0. Type (local) for the server name, select Use Windows NT
Integrated Security, and select Northwind for the database (see Figure 1.2.) Click OK.
Figure 1.2. From now on, this data connection will show up in Visual Studio .NET's Server
Explorer on this machine.
2.
Now you will be back on the Choose Your Data Connection page of the Data Adapter Configuration
Wizard, with the Northwind database in the Data Connection drop-down list. Click Next. This brings you
to the page to select the query type on which the data adapter will be based. Leave the default of Use
SQL Statements, and click Next. In the text box that asks What Data Should the Data Adapter Load
into the Dataset?, type the following:
3.
Select CustomerID, CompanyName From Customers
Note
By default, the Data Adapter Configuration Wizard creates select
statements not only for selecting (viewing) data, but also for
inserting, updating, and deleting. If you don't need these other
options, click the Advanced Options button at the bottom-left corner
of the dialog box. Deselect the check box that reads Generate
Insert, Update, and Delete statements. You don't need this because
we are just using the data to fill a ListBox control. Click OK to
close the Advanced Options dialog box.
Click Next to see results of your select statement, as shown in Figure 1.3. If you see something
4.
different from Figure 1.3, you either have entered your select statement incorrectly, or you have
forgotten to deselect the advanced options.
Figure 1.3. Success in creating the data adapter.
4.
Click Finished to create a data adapter and connection object. You then see a new data adapter control
called OleDbDataAdapter1 and a Connection control called OleDbConnection1. Both controls are in
the Components tray below the Form designer.
5.
After you have created the first two controls, it is time to create the Dataset object. Right-click on the
Data Adapter and choose Generate Dataset from the pop-up menu. This opens the Generate Dataset
dialog box. You can keep all the defaults and simply click OK to create a dataset control called
DataSet<number>. (The sequential number might vary if you have generated other dataset controls.)
6.
Now you are ready to create the ListBox control. Drag the ListBox control from the Windows Forms
group in the toolbox and drop it on your form. Stretch the control to the size of your form, and then set
the following properties in Table 1.2 on the ListBox control.
Table 1.2. ListBox Control Property Settings Needed to Bind a DataSet Control
7.
different from Figure 1.3, you either have entered your select statement incorrectly, or you have
forgotten to deselect the advanced options.
Figure 1.3. Success in creating the data adapter.
4.
Click Finished to create a data adapter and connection object. You then see a new data adapter control
called OleDbDataAdapter1 and a Connection control called OleDbConnection1. Both controls are in
the Components tray below the Form designer.
5.
After you have created the first two controls, it is time to create the Dataset object. Right-click on the
Data Adapter and choose Generate Dataset from the pop-up menu. This opens the Generate Dataset
dialog box. You can keep all the defaults and simply click OK to create a dataset control called
DataSet<number>. (The sequential number might vary if you have generated other dataset controls.)
6.
Now you are ready to create the ListBox control. Drag the ListBox control from the Windows Forms
group in the toolbox and drop it on your form. Stretch the control to the size of your form, and then set
the following properties in Table 1.2 on the ListBox control.
Table 1.2. ListBox Control Property Settings Needed to Bind a DataSet Control
7.
Property Setting
DataSource DataSet<Number>
DisplayMember Customers.CompanyName
ValueMember Customers.CustomerID
Although you have bound the dataset to the correct properties in the ListBox control, if you run the
form at this point, you will still see a blank ListBox control on the form.
Now it is time for the one line of code in this sample, in the Load event of the form. Click on the View
Code button in the Solution Explorer, or choose Code from the View menu. In the Code Editor, select
(Base Class Objects) from the Class Name drop-down list, and then select Load from the Methods
drop-down list. Next, type the line of code as displayed here, which tells the data adapter to fill the
dataset with data:
8.
OleDbDataAdapter1.Fill(DataSet1)
Be sure to use the names of the controls you created. Listing 1.1 presents the Load event code
for the form called frmHowTo1_1 in the samples.
Listing 1.1 frmHowTo1_1.vb: Filling the Data Set on Which ListBox1 Is Based
Private Sub frmHowTo1_1_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Me.OleDbDataAdapter1.Fill(Me.DataSet1)
End Sub
How It Works
When the form called frmHowTo1_1 loads, the Fill method of the OleDbDataAdapter1 is called, with the
DataSet1 being passed. Because the DataSource property of ListBox1 was specified as being DataSet1
and the ValueMember and DisplayMember properties are both set appropriately, ListBox1 is populated
with the CustomerID and CompanyName from the Customers table in Northwind. Figure 1.4 shows what the
final form looks like in Design view, and Figure 1.5 shows what it looks like when running.
Figure 1.4. The final design view for your first database how-to.
Figure 1.5. This list is based on the Customers table in the Northwind SQL Server database.
Comments
In the .NET version of Visual Basic, Microsoft went to considerable effort to make the data controls more
robust than ever. One cool thing is that most of the tasks that are done for you in Visual Basic .NET are
discoverable. Even though you are using the data controls on your form, Visual Studio creates the code
under the covers. You can see this code by clicking on the #Region statement that reads like this:
#Region " Windows Form Designer generated code "
Beware: There is much code here, and you don't want to change it. You can learn a lot from reading it
though.
As you continue to use the Data Controls shown here, you will become comfortable with changing various
properties and getting more power and use out of them.
[ Team LiB ]
[ Team LiB ]
1.2 Limit the Data Displayed in a Bound List Box
Even populating a list box with a couple of columns from a table full of data can be a big performance hit.
This How-To shows you how to create a parameterized SQL statement to limit the items that are displayed in
the list box, thus giving you better performance on your forms.
You have hundreds of thousands of customers in your database, and you don't want the list box loaded up
with the whole customer table. How can you limit the data that is displayed in your list box?
Technique
You are going to make a copy of the form that you created in How-To 1.1. You will then add a Label and
TextBox control that the Select statement contained within the OleDbDataAdapter control will query
against to limit the data displayed in the list box. A command button will be added to allow you to call the Fill
method of the OleDbDataAdapter control whenever you update the text box, and then you can click the
command button (see Figure 1.6 ).
Figure 1.6. You can now limit the amount of data loaded into the list box.
Steps
To get started with this How-To, right-click the form you created in How-To 1.1, which should be listed in the
Solutions Explorer. Choose Copy from the pop-up menu. Next, right-click the project in the Solution
Explorer, and choose Paste from the pop-up menu. You will now have a new Class object in the Solutions
Explorer called Copy Of whatever the previous name of the form was . Rename the new form that you have
created to the name you desire. Then, with that form highlighted, click on the Code button above the
Solutions Explorer. Change the first line of code to say this:
Public Class <Name of the new form>
You see, VS does not change the line of code automatically for you. It thinks you have a duplicate Class
definition.
Now you can see that the icon of the form is correct. You can continue with the steps of the How-To.
Select the Data Adapter that you created. In the Properties pane, you will see the CommandText property when
click on the SelectCommand property plus sign. Replace the CommandText property with the following comman
1.
SELECT CustomerID, CompanyName FROM Customers WHERE (CompanyName LIKE ? + '%')
You will learn more about the Select statement in Chapter 3 . However, the WHERE clause used here comp
CompanyName to a parameter that will be supplied, as indicated by the ?. This will be performed using co
the final step of this How-To. The % is a wildcard that tells the server to make it a fuzzy search.
Resize the ListBox control, and leave room at the top of the form for the Label, TextBox, and Command button
Create these three controls, setting the properties described in Table 1.3 .
Label
Text
Customer
TextBox
Name
txtCustLimit
Text
A
Command Button
Name
btnLoadList
Text
Load List
Table 1.3. Label, TextBox, and Command Button Control Property Settings
Object Property Setting
2.
Double-click the new command button you just created called btnLoadList . Enter the code in Listing 1.2 in th
3.
Click event of the btnLoadList button. This code loads the data entered from txtCustLimit into the parame
of the OleDBDataAdapter1 , which was created by using the ? in the Select statement of the data adapter. T
Dataset1 is cleared of its data with the Clear method. Finally, DataSet1 is refilled with data based off the valu
txtCustLimit , using the data adapter.
Listing 1.2 frmHowTo1_2.vb : Submitting a Parameter to a DataAdapter and Filling the Dataset
3.
Private Sub btnLoadList_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnLoadList.Click
Me.OleDbDataAdapter1.SelectCommand.Parameters(0).Value = _
Me.txtCustLimit.Text
Me.DataSet1.Clear()
Me.OleDbDataAdapter1.Fill(Me.DataSet1)
End Sub
Note
There is one big difference here between an OleDbDataAdapter and a SqlDataAdapter
. Whereas the OleDbDataAdapter takes a ? to specify a parameter within the Select
statement, the SqlDataAdapter requires a named parameter such as @parCustLimit .
Therefore, instead of the select statement in step 1 being this:
SELECT CustomerID, CompanyName FROM Customers WHERE (CompanyName LIKE ? + '%')
It would be this:
SELECT CustomerID, CompanyName FROM Customers WHERE (CompanyName LIKE @parCustLimit + '%')
The naming of the actual parameter is up to you.
Highlight and delete the Load event for the form because you don't want to just fill the event when the form loa
You want the user to click btnLoadList .
4.
How It Works
When the form you created for this How-To loads, or when you're using the form called frmHowTo1_2 , you
will see a blank ListBox control with a text box on top with the letter A in it. If you click the command button
called btnLoadList , the list box becomes filled with values based on the letter (or letters) in
txtCustLimit and on the code described in step 3.
Comments
Try entering a few other letters, and then try entering no letters. What happens? You limit the list more by
the number of letters you enter, and you get all entries when you don't enter any letters.
The method displayed here, although simple, is powerful, and it can be used in a variety of ways.
You can continue building on this form for the next few How-Tos. If you want to copy your form and start a
new one as described at the beginning of the steps for this one, you have the instructions there. Otherwise,
by the time you reach How-To 1.8, you will have a data entry form that you can use. Each step, however, is
available in the sample solution for this chapter.
[ Team LiB ]
[ Team LiB ]
1.3 Bind and View Individual Text Boxes Based Off a Selected List Box Item
Using a list box similar to the one in the previous How-To, in this How-To, you will learn how to create
additional OleDbDataAdapter s and DataSets and bind them to individual text boxes for viewing data.
Although the list box is nice for displaying a couple of fields in my form and limiting the rows displayed, how
do you list the detail in individual text boxes by clicking on an item in the list box?
Technique
You are going to enhance the form that you created in How-To 1.2 to use additional data controls,
specifically another data adapter and dataset. You will set up the select statement in the new data adapter
to take the selected list box item as a parameter. The dataset will then be filled with data, and some text
boxes with the dataset set as the data source will display the current record. You can see an example of this
in Figure 1.7 .
Figure 1.7. You can bind text boxes to datasets as well as list boxes.
Steps
To go further with the form with which you have been working, you will want to rename the data adapter,
dataset, and list box currently on the form to something more meaningful. You can see this in Table 1.4 .
ListBox
Name
ListBox1
lstCustomers
OleDbDataAdapter
Name
OleDbDataAdapter1
odaCustomerList
DataSet
Name
DataSet1
dsCustomerList
Table 1.4. Changes to Current Objects on the Form
Object Property Old Setting New Setting
Tip
Name your objects at the time you first create them. This is true of your
solutions, projects, and forms, as well as controls used on forms. With the .NET
languages being so class and code driven, some items take multiple steps to
rename. Visual Studio doesn't seem to catch all the places in code that need to
be changed. Renaming a form is a good example. Remember that you had to
change the Public Class statement in the code to have it match the new name of
the form.
Drop another Data Adapter control on the form from the Data group of the toolbox. Use the existing data
connection, specify that you will use SQL statements, and assign the following select statement that will
use a parameter supplied at runtime by using the selected list box item.
1.
SELECT CustomerID, CompanyName, ContactName, ContactTitle, Address, City, Region,
PostalCode, Country, Phone, Fax FROM Customers WHERE (CustomerID = ?)
You can click the Advanced Options button on the select statement page and deselect creating the
Insert, Update, and Delete commands. Finish the Data Adapter Wizard and rename the control
odaCustomerIndividual .
Right-click odaCustomerIndividual and choose Generate Dataset from the pop-up menu. Create a
new dataset called dsCustomerIndividual . Click OK. As of this writing, VS places a 1 at the end of
name of the dataset you specified. Clean up the name by removing the 1. Now you should have two data
adapters: odaCustomerList and odaCustomerIndividual , and two datasets: dsCustomerList
2.
3.
and dsCustomerIndividual .
Now it's time to add the text boxes. Resize the form so that it allows you to add a column of text boxes
with labels beside them. You will then add the labels and text boxes, setting the Text property of the text
boxes to the column names in the Customers table as supplied by dsCustomerIndividual. The Text
property of text boxes falls under the Data Binding category in the property sheet. Table 1.5 describes
the controls and their property settings. Refer to Figure 1.8 for an example of where to place them.
Figure 1.8. Letting users know when they can edit data is helpful.
Label
Text
Customer ID
Label
Text
Company Name
Label
Text
Contact
Label
Text
Contact Title
Label
Text
3.
Address
Label
Text
City
Label
Text
Region
Label
Text
Country
Label
Text
Phone
Label
Text
Fax
TextBox
Name
txtCustomerID
Text
dsCustomerIndividual - Customers.CustomerID
TextBox
Name
txtCompanyName
Text
dsCustomerIndividual - Customers.CompanyName
TextBox
Name
txtContact
Text
dsCustomerIndividual - Customers.Contact
TextBox
Name
txtContactTitle
Text
dsCustomerIndividual - Customers.ContactTitle
TextBox
Name
txtAddress
Text
dsCustomerIndividual - Customers.Address
TextBox
Name
txtCity
Text
dsCustomerIndividual - Customers.City
TextBox
Name
txtRegion
Text
dsCustomerIndividual - Customers.Region
TextBox
Name
txtPostalCode
Text
dsCustomerIndividual - Customers.PostalCode
TextBox
Name
txtCountry
Text
dsCustomerIndividual - Customers.Country
TextBox
Name
txtPhone
Text
dsCustomerIndividual - Customers.Phone
TextBox
Name
txtFax
Text
dsCustomerIndividual - Customers.Fax
Table 1.5. New Label and TextBox Control Property Settings for the Form
frmHowTo1_3
Object Property Setting
Now it's time for the code. To start off, you will change the Click event code for the button called
btnLoadList. The first three lines of code are basically the same as in the last How-To, except that the
name was changed as needed, and some lines were added to comment the code.
4.
Listing 1.3 frmHowTo1_3.vb : Adding the Call to the RefreshIndividual Subroutine
4.
Private Sub btnLoadList_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnLoadList.Click
'— Store the text entered to limit the list box to the
' data adapter's parameter
Me.odaCustomerList.SelectCommand.Parameters(0).Value = _
Me.txtCustLimit.Text
'— Clear the current data in the dataset
Me.dsCustomerList.Clear()
'— Fill the customer list dataset
Me.odaCustomerList.Fill(Me.dsCustomerList)
'— Fill the initial entry's individual dataset
RefreshIndividual()
End Sub
The only new line of code is the one just before the End Sub , which calls the subroutine
RefreshIndividual for the first item in the newly populated list box. This subroutine first
handles clearing the dataset called dsCustomerIndividual . It ensures that a customer is
chosen in the list box and then places the selected item into the parameter value for
odaCustomerIndividual . The dataset called dsCustomerIndividual is then filled, displaying
the data in the text boxes bound to the dataset.
Listing 1.4 frmHowTo1_3.vb : Refreshing the Dataset on Which the Text Boxes Are Based
Private Sub RefreshIndividual()
'— Clear individual customer dataset
Me.dsCustomerIndividual.Clear()
'— Check to see if an item was selected
If lstCustomers.SelectedIndex <> -1 Then
'— Store the selected customer ID into the
' parameter of the SQL data adapter
Me.odaCustomerIndividual.SelectCommand.Parameters(0).Value = _
Me.lstCustomers.SelectedItem(0)
'— Fill the dataset
Me.odaCustomerIndividual.Fill(Me.dsCustomerIndividual)
End If
End Sub
The only other code is required when a new item is selected in the list box. You want to refresh the
text boxes with the new data. This code is on the SelectedIndexChanged event for the
lstCustomers list box.
Listing 1.5 frmHowTo1_3.vb : Call the RefreshIndividual Routine
Private Sub lstCustomers_SelectedIndexChanged(ByVal sender As System.Object,
ByVal e As System.EventArgs) _
Handles lstCustomers.SelectedIndexChanged
'— Fill the current list item's individual dataset
RefreshIndividual()
End Sub
How It Works
After the user types a letter into the txtCustLimit text box and clicks btnLoadList , the list box is
populated with the items that match the text in the text box. After lstCustomers is populated, the user
sees the details for the first item in the list box that is displayed in the text boxes. This occurs within the
routine called RefreshIndividual . The selected item is used for the parameter for the data adapter
called odaCustomerIndividual , then filling the dataset called dsCustomerIndividual . As the user
selects new items in the list box, the data that corresponds to the selected item is displayed.
Tip
Always try to break your code into specific routines such as the subroutine
RefreshIndividual . That way when someone tries to read the code, the code
is easy to read, you don't make mistakes by typing the same code two or more
times, and you only have to change the code in one place if necessary.
Comments
Binding text boxes to datasets saves work when switching from one record to another because you don't
have to specifically load each text box with data each time. It also gets easier every time you use a data
adapter and dataset in combination when manipulating data on your forms.
Bound datasets are particularly useful as you edit, add, and delete data on your forms, as you will see in the
following How-Tos.
[ Team LiB ]
[ Team LiB ]
1.4 Edit and Update Data Using Bound Controls
Although viewing data is fine in some situations, the real power comes in being able to edit the data in the
text box and update the data in the server. In this How-To, you learn just that, using some new methods
and properties from the various data controls, including autogenerated commands that create update,
insert, and delete SQL statements for you. This How-To also introduces you to the BinderContext class ,
which is used to perform updates with bound controls.
The form as created in How-To 1.4 is great if you just want to view data for various records. But what if you
want to let users edit and update the data?
Technique
Continuing with the form you used in the previous How-Tos, you are going to add a few command buttons
with code that will perform the following:
Edit. Toggle the look of the text boxes to let the user know that he can edit the data in the controls by
giving the controls a sunken look.
Save. Save the changes made to the data back to the server. Then toggle the look of the text boxes
back to flat so that the user knows he can't edit them.
Cancel. Toggle the text boxes back to flat so that the user knows he can't edit them anymore, but
don't save the data.
It is important to let users know when they can edit and when they can't. By toggling the style of the text
boxes between flat and sunken and the color between gray and white, users have a definite clue that they
can edit the data at certain times (see Figure 1.8 ).
Another useful item to note about this How-To is the introduction of the BindingContext class. This class
helps you work with data bound controls. Each control on a Windows form has a BindingContext object as
well as BindingContext objects for any controls that are contained within that control. Each form also has
a BindingContext object. BindingContext objects manage BindingManagerBase class object(s) for
each control. Through the BindingContext object, you can manage editing and updating data back to the
server. BindingManagerBase objects help with synchronization of datasets with controls. You are going to
use the BindingContext class throughout the rest of this chapter, but only a couple of methods.
Steps
Open the solution for the chapter called "VB .NET How-To Chapter 1 ," and run the application. From the
main form, click the command button with the caption "How-To 1.4." Click the Load List button . Along with
the list being filled with customers whose names start with A , you will see the detail How-To fill in on the
right side of the form with the first customer in the list. Click Edit. You will now be able to change the data in
the text boxes. After you have changed a couple of fields, click Save. If you select another customer from
the list box, select the one you changed. You will see that your changes have in fact been saved. If you click
Cancel instead of Save, your changes will not be saved. Note that if you change the name of the customer,
you must load the list again to see the changes in the list box.
Add the three command buttons to your form as described in Table 1.6 and as displayed in Figure 1.8 .
1.
Command Button
Name
btnEdit
Caption
&Edit
Command Button
Name
btnSave
Caption
&Save
Command Button
Name
btnCancel
Caption
&Cancel
Table 1.6. Command Buttons to Edit, Save, and Cancel Changes to Data
Object Property Setting
1.
Add the code shown in Listing 1.6 to the btnEdit Click event.
Listing 1.6 frmHowTo1_4.vb : Calling the ActiveEditing Subroutine from the btnEdit Command Button
2.
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
This calls the routine called ActivateEditing , listed here. This code iterates through all the controls on
the form and uses the TypeOf condition to check whether the current control is a text box. It also ensures
that the control is not the txtCustLimit text box. If the control is a text box and the parameter called
bEnable has been passed in as True , then the sunken look is given to the text box using the
BorderStyle and the BackColor property is set to white. Otherwise, the BorderStyle is set to
FixedSingle , which is flat, and the BackColor is set to the backcolor of the form. The Enabled
property of the text box is set to whatever bEnabled is: True or False .
Listing 1.7 frmHowTo1_4.vb : Toggling the Enabled Property and Look of Text Boxes
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
Add the code to the Click event of the btnSave command button. This code calls a new routine called
SaveRecord , which performs the actual save. The ActivateEditing is then called, passing False to disable
the controls because you are finished editing.
Listing 1.8 frmHowTo1_4.vb : Calling the SaveRecord Routine and Disabling the Text Boxes by Calling
ActivateEditing
3.
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
Following is the code for the subroutine called SaveRecord . This routine calls the EndCurrentEdit
method of the BindingContext class, passing in the dataset called dsCustomerIndividual , and
specifying the Customers table. Then the Update method is called off the data adapter called
odaCustomerIndividual , passing the same parameters. This updates the changes back to the dataset
Finally, the dataset changes are sent back to the server.
Listing 1.9 frmHowTo1_4.vb : Saving the Data Back to the Server
Private Sub SaveRecord()
'— Use the BindingContext class to end current editing
' so that we can update the server.
Me.BindingContext(Me.dsCustomerIndividual, "Customers").EndCurrentEdit()
'— Perform the requested task at the dataset
' level using the data adapter
Me.odaCustomerIndividual.Update(Me.dsCustomerIndividual, "Customers")
'— By accepting the changes, the data gets sent back to the server
Me.dsCustomerIndividual.AcceptChanges()
End Sub
Note
If you haven't read about ADO.NET yet, then you might be confused about doing an
update to the dataset, accepting changes, and sending the changes back to the server.
ADO.NET works using disconnected data. When you create a dataset by using a data
adapter, the data is actually created using XML. To see proof of this, take a look at
dsCustomerIndividual.xsd, found in the Solutions Explorer.
<xsd:schemaid="dsCustomerIndividual"targetNamespace="http://www.tempuri.org /
dsCustomerIndividual.xsd"xmlns="http://www.tempuri.org/ dsCustomerIndividual.xsd"xmlns:
xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:
xml-msdata"attributeFormDefault="qualified" elementFormDefault="qualified">
<xsd:element name="dsCustomerIndividual" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="Customers">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="CustomerID" type="xsd:string" />
<xsd:element name="CompanyName" type="xsd:string" />
<xsd:element name="ContactName" type="xsd:string" minOccurs="0" />
<xsd:element name="ContactTitle" type="xsd:string" minOccurs="0" />
<xsd:element name="Address" type="xsd:string" minOccurs="0" />
<xsd:element name="City" type="xsd:string" minOccurs="0" />
<xsd:element name="Region" type="xsd:string" minOccurs="0" />
<xsd:element name="PostalCode" type="xsd:string" minOccurs="0" />
<xsd:element name="Country" type="xsd:string" minOccurs="0" />
<xsd:element name="Phone" type="xsd:string" minOccurs="0" />
<xsd:element name="Fax" type="xsd:string" minOccurs="0" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
<xsd:unique name="Constraint1" msdata:PrimaryKey="true">
<xsd:selector xpath=".//Customers" />
<xsd:field xpath="CustomerID" />
</xsd:unique>
</xsd:element>
</xsd:schema>
This is all performed under the covers, so the good news is that you don't have to know XML to work with
datasets and ADO. More information on this can be found in Chapter 3 .
The last task is to give you the capibility to cancel the edits. You do this by placing the following code in the
Click event on btnCancel . Calling the CancelCurrentEdit method of the BindingContext object for the
form, the current edits are cancelled. Next, the text boxes are disabled using the routine ActivateEditing.
Listing 1.10 frmHowTo1_4.vb : Canceling Changes to Data and Disabling the Text Boxes Again
4.
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.
Me.BindingContext(Me.dsCustomerIndividual, _
"Customers").CancelCurrentEdit()
ActivateEditing(False)
End Sub
How It Works
When the user clicks the btnEdit button, the ActiveEditing routine alerts the user that he can edit the
data in the text boxes. The text boxes are enabled.
If the user then clicks the btnSave button, the data is updated to the dataset and then back to the server. If
the user clicks the btnCancel button, the edits are canceled. In both cases, the ActivateEditing routine
is called to disable the text boxes and let the user know that the text boxes cannot be edited.
Comments
This How-To showed the bare bones for editing and updating data. It presented a basic technique to get
started. As you continue, you will learn methods to add and delete records, as well as handle errors.
Using ADO.NET, which you use for bound controls, takes some getting used to if you have worked with other
data accessing methods such as ADO and DAO. The BindingContext and BindingManagerBase objects
make working with bound objects in code much more manageable.
[ Team LiB ]
[ Team LiB ]
1.5 Add and Delete Records Using Bound Controls
Besides editing data, adding new records and deleting records in a table are obviously important features.
This How-To shows you just that, taking advantage of the BinderContext class.
Besides being able to edit current records that already exist, users need to be able to add and delete records
as well. How do you add and delete records using bound controls?
Technique
To create the Add New Record feature, you will add a button called btnAddNew that has code behind it. You
will use the BindingContext object again to add a new record by using the AddNew method . A module
variable will be added to the form to keep track of whether a record is being added or edited. If a new record
is being added, then when the update is performed, the application needs to reload the data in the list box in
case the new record's CompanyName data falls into the chosen list limit that is specified in the
txtCustLimit text box.
To create the Delete Record feature, you will add a button called btnDelete . This button will have code
behind it that will use the RemoveAt method of the ContextBinding object to remove the record from the
dataset. The data will then be posted back to the server.
Steps
Open the solution for the chapter called "VB .NET How-To Chapter 1 ," and run the application. From the
main form, click on the command button labeled How-To 1.5. Click the Load List button . Click the button
labeled New. Enter the text ALF for Customer ID and Alfred's Fried Foods in the Company Name.
Then click the button labeled Save, and see the record you just entered added to the list. After the record
has been entered, you can test the delete feature by clicking on the button named Delete. The record goes
away, and the list is rebuilt.
Add a new command button under btnEdit , and then set the Name property to btnNew and the
Caption property to &Save .
1.
Add a new module-level variable called mbAddNew , which is a Boolean variable to keep track of whether
you are adding a new record. This variable will be placed outside of your routines, just under the forms
code. You can see this in Figure 1.9 .
Figure 1.9. By placing this variable just underneath Windows Form Designer Generated Code
and declaring it Private, routines inside the Class can see it, but those outside cannot.
2.
Tip
You can collapse and expand routines that you are working on within modules.
This makes it handy when you are working on new routines (which can be
expanded) and don't want to mess with old routines (which can be collapsed).
Add the following code to the Click event of the new command button btnNew . This code first sets the
Boolean variable called mbAddNew to True . It then uses the AddNew method of the form's
BindingContext object to add a new record to the dsCustomerIndividual dataset. Finally, the code
calls the ActiveEditing routine to enable the text boxes.
Listing 1.11 frmHowTo1_5.vb : Adding a New Record to the dsCustomerIndividual Dataset
and Toggling Text Boxes
3.
Private Sub btnNew_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnNew.Click
mbAddNew = True
'— Using the BindingContext class add a new record
Me.BindingContext(Me.dsCustomerIndividual, "Customers").AddNew()
ActivateEditing(True)
End Sub
Modify the Click event of the btnSave to test whether the mbAddNew flag has been set to True ,
meaning that a new record is being added. If True , then after saving the record by calling the
SaveRecord and ActivateEditing routines, the LoadList and RefreshIndividual are called to
load the new record's data. Note that the SaveRecord, ActiveEditing , and RefreshIndividual
routines have not changed from How-To 1.4. The mbAddNew variable is then set to False .
Listing 1.12 frmHowTo1_5.vb : Saving the Changed Data, Toggling Text Boxes, and Reloading
the List Box and First Record in the List
4.
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)
If mbAddNew Then
LoadList()
RefreshIndividual()
mbAddNew = False
End If
End Sub
Modify the Click event for the btnCancel button to reset the mbAddNew variable to False , as seen in
Listing 1.13 .
Listing 1.13 frmHowTo1_5.vb : Canceling the Edit and Resetting the mbAddNew Variable
5.
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.
Me.BindingContext(Me.dsCustomerIndividual, "Customers").CancelCurrentEdit()
ActivateEditing(False)
mbAddNew = False
End Sub
Now it is time to add the delete functionality. To do this, add the following code to the Click event of
the new button called btnDelete . The first line of the code you added begins by introducing a new
method called RemoveAt and a new property called Position, both used with the BindingContext
6.
object. You will work from the inside out. The Position property tracks the current position in the
dataset, in this case dsCustomerIndividual. The RemoveAt method marks the record that is at the
position passed to it for deletion.
Next, the Update method of the odaCustomerIndividual adapter is used to call the DELETE SQL
statement command against the dataset, deleting the actual rows in the data set. The AcceptChanges
method is called to send the changes to the dataset, a delete in this case, back to the server. Finally, the
LoadList , RefreshIndividual , and ActivateEditing subroutines are called to refresh the list,
refresh the first record in the list for the text boxes, and toggle the text boxes so that the user knows he
can't edit them.
Listing 1.14 frmHowTo1_5.vb : Deleting the Selected Record and Reloading the List Box
6.
Private Sub btnDelete_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnDelete.Click
'— Mark the row for deletion using the RemoveAt method of the BindingContext
Me.BindingContext(Me.dsCustomerIndividual, _
"Customers").RemoveAt(Me.BindingContext(Me.dsCustomerIndividual,
"Customers").Position)
'— Perform the requested task at the dataset
' level using the data adapter
odaCustomerIndividual.Update(dsCustomerIndividual, "Customers")
'— By accepting the changes, the data gets sent back to the server
dsCustomerIndividual.AcceptChanges()
'— Reload the list
LoadList()
'— Display the first record
RefreshIndividual()
'— Disable the text boxes
ActivateEditing(False)
End Sub
How It Works
When the user clicks the btnNew button, a flag (mbAddNew ) is set to True , the dataset is set for adding a
record with the AddNew method of the BindingContext , and the text boxes are enabled for editing.
If the user then clicks the btnSave button, the data is updated to the dataset and then back to the server.
If the user clicks the btnCancel button, the edits are canceled. In both cases, the mbAddNew variable is
set to False and the ActivateEditing routine is called to disable the text boxes and let the user know
that the text boxes are not available for editing. Finally, if the btnSave button was clicked and the mbAddNew
was set to True , the LoadList and RefreshIndividual routines are called.
When the user clicks the btnDelete button, the record is deleted from the recordset and then from the
server. The list box is reloaded and the first record in the list is displayed in the text boxes. The text boxes
are then disabled.
Comments
Here you have the basic commands needed to create a full-fledged data entry form. You can add, edit, and
delete information from the form. This actually takes less code than if you use Visual Basic 6.0.
The BindingContext object really goes a long way to helping you work with bound data.
[ Team LiB ]
[ Team LiB ]
1.6 Take Care of Error Handling with Bound Controls
When dealing with database tasks, you are going to get runtime errors. In .NET, we call the various types of
errors you can get exceptions. This How-To shows examples of what exceptions could occur and how to
handle them using the Try, Catch, and Finally statements.
Adding and deleting records is fine, but what happens if an error occurs? You tried to delete an existing
company, and got the screen that appears in Figure 1.10.
Figure 1.10. This is an unhandled error, called an exception in .NET.
How do you make it so errors are handled gracefully within the application using bound controls?
Technique
Error handling is one of the most important aspects of working with data, between when a user is entering
data and updating the server. If you don't have proper error handling, your system will, in the best situation,
give an ugly error message, and in the worst, blow up and put bad data in your system. In Visual Studio
.NET, errors are classes called exceptions. Many different (inherited) types of exceptions exist.
Run-time exceptions can occur in just about any part of your application. They can be handled by using
Try...Catch...Finally or they can be unhandled, where you will see the error in Figure 1.11.
Figure 1.11. This error was thrown up from one subroutine to the one that called it.
Take a look at a common way to trap exceptions shown in Listing 1.15.
Listing 1.15 Standard Code for Handling Exceptions
Private Sub MySub()
Try
'—Code to be handled here
Catch dataException as Exception
MessageBox.Show(dataException.Message)
Finally
'—Code that will occur regardless of if an error occurs.
End Try
End Sub
Following are some basic points to help you when working with exceptions and Try...Catch...Finally
blocks:
The name of the exception object can be whatever you want it to be. dataException was just used as
an example.
Specific types of exceptions inherit from the base class of System.Exception. OleDbException is
one of those classes, and you will see an example of using this class in the following steps.
You can use the Throw statement within a Catch statement to throw the exception back up to a
calling subroutine.
You can use the When clause on the Catch statement to trap for specific exceptions.
When multiple Catch statements are used, each one is executed unless an End Try or End Sub is
placed within a Catch block, as in this How-To.
You can use multiple Catch statements to handle various possible exceptions that can occur.
You will see an example of these bullets in the following steps.
Steps
Taking the form with which you have been working, you are going to modify it to trap exceptions when the
record is being saved (either for additions or editing) and when the record is deleted. You will also add some
code in the event when closing the form.
Modify the code in the Click event of the command button called btnSave. You will surround the
SaveRecord routine call with a Try...Catch...End Try block. If an exception occurs, the Show
method of the MessageBox class is called, passing the Message property of the Exception object
called saveException. Next, the subroutine is exited. If no errors occur, then life goes on, and so
does the subroutine.
1.
Listing 1.16 frmHowTo1_6.vb: Code Added to btnSave Click Event to Trap Save Exceptions
Private Sub btnSave_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnSave.Click
Try
'— Save the information
SaveRecord()
Catch saveException As Exception
MessageBox.Show("The following error has occurred: " & _
saveException.Message, "Error Saving Record")
Exit Sub
End Try
'— Disable the text boxes
ActivateEditing(False)
If mbAddNew Then
LoadList()
RefreshIndividual()
mbAddNew = False
End If
End Sub
Modify the SaveRecord routine to "throw" the exception up to the btnSave_Click subroutine, or
whatever happens to have called the SaveRecord routine. Following is the SaveRecord subroutine
with the new Try...Catch...End Try block added, along with the Throw statement.
Listing 1.17 frmHowTo1_6.vb: Pass the Exception Back Up to the Calling Routine
2.
Private Sub SaveRecord()
Try
'— Use the BindingContext class to end the current editing so
' that we can update the server.
Me.BindingContext(Me.dsCustomerIndividual, _
"Customers").EndCurrentEdit()
'— Perform the requested task at the dataset
' level using the data adapter
odaCustomerIndividual.Update(dsCustomerIndividual, "Customers")
'— By accepting the changes, the data gets sent back to the server
dsCustomerIndividual.AcceptChanges()
Catch saveException As Exception
Throw saveException
End Try
End Sub
Now it's time to deal with adding exception handling to the btnDelete Click event, as seen next.
The Try statement is used to wrap the code that performs deletion of the data. The code then uses a
Catch statement to check whether the exception that occurs is a specific OleDbException, 3621,
which is an error having to do with trying to delete a record when related records exist in another
table. Note that you could—and in fact should—assign this to a constant value. Because
delException has been caught as an OleDbException, you can look at the NativeError property
of the first error in the Errors collection to get the actual OleDb error number. If the error is not 3621,
then the exception is trapped with the next Catch statement, and a messagebox is displayed. If
errors occur, then the subroutine is exited before the final lines of code are executed.
Listing 1.18 frmHowTo1_6.vb: Catching Exceptions When You're Deleting a Record
3.
Private Sub btnDelete_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnDelete.Click
Try
'— Mark the row for deletion using the RemoveAt
' method of the BindingContext
Me.BindingContext(Me.dsCustomerIndividual,
"Customers").RemoveAt(Me.BindingContext(Me.dsCustomerIndividual,
"Customers").Position)
'— Perform the requested task at the dataset
' level using the data adapter
odaCustomerIndividual.Update(dsCustomerIndividual, "Customers")
'— By accepting the changes, the data gets sent back to the server
dsCustomerIndividual.AcceptChanges()
Catch delException As System.Data.OleDb.OleDbException _
When delException.Errors(0).NativeError = 3621
MessageBox.Show("An error occurred because of related order records.",
"Error Deleting Customer", _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Exit Sub
Catch delException As Exception
MessageBox.Show(delException.Message, "Error Deleting Customer",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Exit Sub
End Try
'— Reload the list
LoadList()
'— Display the first record
RefreshIndividual()
'— Disable the text boxes
ActivateEditing(False)
End Sub
How It Works
When an exception occurs within the Try...Catch...End Try block, the Catch statements are compared
when a When clause is used or when the code is simply executed. If a Throw statement is used, then an
execution is thrown back up a level to the Try...Catch...End Try block containing the call to the routine
where the Throw statement occurred. You can see an example of this in Figure 1.11.
Comments
Microsoft has gone to great length to let you control how you handle exceptions in .NET with the various
languages. You can be as creative as you need to by using the Try...Catch...End Try block with all the
clauses available.
Exceptions bring back plenty of information so that you can create pretty slick error handling. You can use
exceptions to create a centralized routine that logs errors, or even one that e-mails exception information to
you from your applications.
[ Team LiB ]
[ Team LiB ]
1.7 Put the Finishing Touches on a Data Bound Form
Besides handling the basics, you need to add some finishing touches to a data entry form, such as
enabling/disabling controls based on whether you're on a record. This How-To shows you how to use the
Enabled properties on controls to give the user more direction when using a Windows form (see Figure 1.12
).
Figure 1.12. You will create this complete form by How-To 1.7, with all the bells and whistles that
users expect from a good data entry form.
Although the majority of the major issues are taken care of for the form you created so far in the chapter,
your users become confused about when to push some of the buttons. How do you get the buttons to reflect
when the users can click them, and what other finishing touches might help the form?
Technique
An important part of user interfaces is letting the user know when he has access to certain features on the
form. In this case, you will see how to do the following:
Toggle the enabled property of the btnSave , btnCancel , btnNew , and btnDelete at the
appropriate moments, such as when a record is highlighted in the list box.
Add a command button to close the form.
Add code to the Closing event of the form that tests whether you have made changes to the current
record, and if so, whether you want to save the changes.
You can see an example of particular command buttons being enabled based on the current action being
performed in the form in Figure 1.13 .
Figure 1.13. This form allows users to access command buttons only when the functionality is
available.
Steps
Continuing on with the form that you have been using, you are going to make the changes just mentioned in
the previous bulleted list.
Start by modifying two routines already created: RefreshIndividual and ActivateEditing
subroutines. Then check whether a customer has been selected in lstCustomers . If not, then the two
buttons, btnEdit and btnDelete, are disabled. If a customer hasn't been selected, the two buttons are
enabled, and the dsCustomerIndividual dataset control is refreshed.
Listing 1.19 frmHowTo1_7.vb : Toggling the Enabled Property of the btnEdit and btnDelete
Buttons
1.
Private Sub RefreshIndividual()
'— Clear individual customer dataset
Me.dsCustomerIndividual.Clear()
If lstCustomers.SelectedIndex = -1 Then
btnEdit.Enabled = False
btnDelete.Enabled = False
Else
btnEdit.Enabled = True
btnDelete.Enabled = True
Me.odaCustomerIndividual.SelectCommand.Parameters(0).Value =
lstCustomers.SelectedItem(0)
'— Fill the dataset
Me.odaCustomerIndividual.Fill(Me.dsCustomerIndividual, "Customers")
End If
End Sub
Similarly, you will add code to the ActivateEditing subroutine to toggle the Enable property of
the various command buttons, depending on their purpose. Listing 1.20 shows the entire routine.
Listing 1.20 frmHowTo1_7.vb : Toggling the Enabled Property of btnEdit and btnDelete
Buttons
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
'— Enable/Disable the appropriate buttons
btnEdit.Enabled = Not bEnable
btnNew.Enabled = Not bEnable
btnDelete.Enabled = Not bEnable
btnCancel.Enabled = bEnable
btnSave.Enabled = bEnable
'— Set the focus to the CustomerID text box
If bEnable Then
Me.txtCustomerID.Focus()
End If
End Sub
The specific lines of code added are shown here:
'— Enable/Disable the appropriate buttons
btnEdit.Enabled = Not bEnable
btnNew.Enabled = Not bEnable
btnDelete.Enabled = Not bEnable
btnCancel.Enabled = bEnable
btnSave.Enabled = bEnable
These buttons are handled as the other buttons are—by taking the opposite value to which bEnable
is currently set, and using it to toggle the Enabled property.
Finally, if the bEnable flag is True , then focus is moved to the txtCustomerID text box using the
following lines of code:
'— Set the focus to the CustomerID text box
If bEnable Then
Me.txtCustomerID.Focus()
End If
End Sub
Add a new command button, with the properties Name and Text set to btnClose and &Close ,
respectively. Place the code in Listing 1.21 for the Click event.
Listing 1.21 frmHowTo1_7.vb : Close the Form
2.
Private Sub btnClose_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnClose.Click
Me.Close()
End Sub
Add some code to the Closing event of the form. Listing 1.22 tests whether the btnSave button is
enabled. If it is, the MessageBox method is evoked, asking the user if he wants to save changes that
were made. If so, then the SaveRecord is called within a Try...Catch...End Try block.
Listing 1.22 frmHowTo1_7.vb : Checking Whether the User Wants to Save a Record Before
Closing
3.
Private Sub frmHowTo1_7_Closing(ByVal sender As Object, _
ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
'— If an edit or add has been requested, enabling the Save button,
' then prompt to save the record
If btnSave.Enabled Then
If MessageBox.Show("Would you like to save the current record?", _
"Save Record?", MessageBoxButtons.YesNo) = _
DialogResult.Yes Then
Try
'— Save the information
SaveRecord()
Catch saveException As Exception
If MessageBox.Show("The following error has occurred: " &
saveException.Message & vbCrLf & vbCrLf & _
"Continue with closing the form?", "Error Saving Record",
MessageBoxButtons.YesNo) = DialogResult.No Then
e.Cancel = True
End If
End Try
End If
End If
End Sub
How It Works
In the modifications made to the form in this How-To, many things happen depending on what is occurring.
When the user clicks the btnEdi t button, btnEdit , btnNew , and btnDelete are disabled, and
btnCancel and btnSave are enabled. The opposite is true when btnCancel and btnSave are pressed. If
bEnable is True , then the focus is moved to the txtCustomerID text box.
When the txtClosed button is clicked, the application then checks whether the btnSave command button
has been enabled, meaning data is being edited. If so, then the user is asked whether he wants to save the
current record. If the user does, the system then saves the current information back to the server.
Comments
The tasks displayed in this How-To are just a few of the tasks you can do to make your forms look and feel
more professional. They are also what users come to expect from database applications.
Play with the form a bit more. You're sure to come up with a few more ideas.
[ Team LiB ]
[ Team LiB ]
1.8 Bind Data to ComboBox and DataGrid Controls
Sometimes you might want to use a ComboBox control instead of a ListBox control to display a list of
choices. You also might want to display information in a grid style based on the item chosen in that combo
box. This How-To describes how to bind data to both ComboBox and DataGrid controls.
Instead of using a ListBox control to display customers, you would like to use a ComboBox control to
display them. After you choose a customer, you would like to display information about the orders that
belong to that customer. How do you bind data to the ComboBox and then bind the DataGrid control as
well?
Technique
To bind both the ComboBox and the DataGrid controls, you will use the same properties and coding
techniques that you have used for the ListBox control. You will first create DataAdapter and DataSet
controls to which to set the DataSource properties. The DataAdapter for the DataGrid will include a
parameter that will use the value selected in the ComboBox control.
You will set the DataSource properties of the controls to the DataSet created. That is all you really have to
set for the DataGrid control. For the ComboBox control, you will also set the ValueMember and
DisplayMember properties.
You will then add code to fill the DataSet control to which the DataSource property is set for the
ComboBox control. Finally, you will create a subroutine to store the selected value in the ComboBox in the
DataAdapter that was created for filling the DataSet on which the DataGrid control is based.
After the user has selected a value in the ComboBox that contains the customers, the DataGrid control
displays the orders for that customer, as can be seen in Figure 1.14.
Figure 1.14. Users can display the header information for customer orders using these two
controls.
Steps
You will be starting with a fresh form.
Add a new Windows Form called frmHowTo1_8.
1.
Add the OleDbDataAdapter and DataSet controls with the properties set forth in Table 1.7.
Table 1.7. OleDataAdapter and DataSet Controls
Object Property Setting
OleDataAdapter Name odaCustomerList
SelectCommand OleDbSelectCommand1
CommandText SELECT CustomerID, CompanyName FROM
Customers
DataSet Name dsCustomerList
DataSetName dsCustomerList
OleDataAdapter Name odaOrdersForCustomer
SelectCommand OleDbSelectCommand2
CommandText SELECT OrderID, OrderDate, RequiredDate,
ShippedDate FROM Orders WHERE (CustomerID = ?
) ORDER BY OrderDate
DataSet Name dsOrdersForCustomer
DataSetName dsOrdersForCustomer
Tip
You will want to create the OleDbDataAdapter controls using the
Data Adapter Configuration Wizard, and then set the name after
the DataAdapter has been created. You will want to create the
DataSet controls by right-clicking on the appropriate
OleDbDataAdapter and choosing Generate Dataset. If you have
questions about creating these controls, reread How-To 1.1.
Also, remember that when generating the DataSet, VS always
changes the name by adding a 1 on the end and capitalizing the
first letter. You might want to change it to what you really want in
the properties directly.
2.
Add the ComboBox and DataGrid controls, as well as the Label for the ComboBox, setting the
properties as shown in Table 1.8.
3.
Table 1.8. Label, ComboBox, and DataGrid Controls Property Settings
Object Property Setting
Label Name Label1
Text "Customers to List Orders For:"
ComboBox Name cboCustomers
DataSource dsCustomerList.Customers
DisplayMember CompanyName
ValueMember CustomerID
DataGrid Name dgOrders
DataSource dgOrdersForCustomer.Orders
Add code shown in Listing 1.23 to the Load event of the form. This code fills the dsCustomerList
DataSet control based off the select statement used in the odaCustomerList OleDbDataAdapter
control. After this occurs, the RefreshOrders subroutine is called, displayed in Listing 1.24.
Listing 1.23 frmHowTo1_8.vb: Filling the Dataset Used by the ComboBox Control
4.
Private Sub frmHowTo1_8_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Me.odaCustomerList.Fill(Me.dsCustomerList)
RefreshOrders()
End Sub
Listing 1.24 frmHowTo1_8.vb: Filling the Dataset Used by the DataGrid Control, Based
on the Item Selected in the ComboBox Control
Private Sub RefreshOrders()
'— Clear Orders for customer dataset
Me.dsOrdersForCustomer.Clear()
'— Check to see if an item was selected
If Me.cboCustomers.SelectedIndex <> -1 Then
'— Store the selected customer ID into the parameter
' the SQL data adapter
Me.odaOrdersForCustomer.SelectCommand.Parameters(0).Value = _
Me.cboCustomers.SelectedItem(0)
'— Fill the dataset
Me.odaOrdersForCustomer.Fill(Me.dsOrdersForCustomer)
End If
End Sub
5.
Random documents with unrelated
content Scribd suggests to you:
This eBook is for the use of anyone anywhere in the United
States and most other parts of the world at no cost and with
almost no restrictions whatsoever. You may copy it, give it away
or re-use it under the terms of the Project Gutenberg License
included with this eBook or online at www.gutenberg.org. If you
are not located in the United States, you will have to check the
laws of the country where you are located before using this
eBook.
1.E.2. If an individual Project Gutenberg™ electronic work is derived
from texts not protected by U.S. copyright law (does not contain a
notice indicating that it is posted with permission of the copyright
holder), the work can be copied and distributed to anyone in the
United States without paying any fees or charges. If you are
redistributing or providing access to a work with the phrase “Project
Gutenberg” associated with or appearing on the work, you must
comply either with the requirements of paragraphs 1.E.1 through
1.E.7 or obtain permission for the use of the work and the Project
Gutenberg™ trademark as set forth in paragraphs 1.E.8 or 1.E.9.
1.E.3. If an individual Project Gutenberg™ electronic work is posted
with the permission of the copyright holder, your use and distribution
must comply with both paragraphs 1.E.1 through 1.E.7 and any
additional terms imposed by the copyright holder. Additional terms
will be linked to the Project Gutenberg™ License for all works posted
with the permission of the copyright holder found at the beginning
of this work.
1.E.4. Do not unlink or detach or remove the full Project
Gutenberg™ License terms from this work, or any files containing a
part of this work or any other work associated with Project
Gutenberg™.
1.E.5. Do not copy, display, perform, distribute or redistribute this
electronic work, or any part of this electronic work, without
prominently displaying the sentence set forth in paragraph 1.E.1
with active links or immediate access to the full terms of the Project
Gutenberg™ License.
1.E.6. You may convert to and distribute this work in any binary,
compressed, marked up, nonproprietary or proprietary form,
including any word processing or hypertext form. However, if you
provide access to or distribute copies of a Project Gutenberg™ work
in a format other than “Plain Vanilla ASCII” or other format used in
the official version posted on the official Project Gutenberg™ website
(www.gutenberg.org), you must, at no additional cost, fee or
expense to the user, provide a copy, a means of exporting a copy, or
a means of obtaining a copy upon request, of the work in its original
“Plain Vanilla ASCII” or other form. Any alternate format must
include the full Project Gutenberg™ License as specified in
paragraph 1.E.1.
1.E.7. Do not charge a fee for access to, viewing, displaying,
performing, copying or distributing any Project Gutenberg™ works
unless you comply with paragraph 1.E.8 or 1.E.9.
1.E.8. You may charge a reasonable fee for copies of or providing
access to or distributing Project Gutenberg™ electronic works
provided that:
• You pay a royalty fee of 20% of the gross profits you derive
from the use of Project Gutenberg™ works calculated using the
method you already use to calculate your applicable taxes. The
fee is owed to the owner of the Project Gutenberg™ trademark,
but he has agreed to donate royalties under this paragraph to
the Project Gutenberg Literary Archive Foundation. Royalty
payments must be paid within 60 days following each date on
which you prepare (or are legally required to prepare) your
periodic tax returns. Royalty payments should be clearly marked
as such and sent to the Project Gutenberg Literary Archive
Foundation at the address specified in Section 4, “Information
about donations to the Project Gutenberg Literary Archive
Foundation.”
• You provide a full refund of any money paid by a user who
notifies you in writing (or by e-mail) within 30 days of receipt
that s/he does not agree to the terms of the full Project
Gutenberg™ License. You must require such a user to return or
destroy all copies of the works possessed in a physical medium
and discontinue all use of and all access to other copies of
Project Gutenberg™ works.
• You provide, in accordance with paragraph 1.F.3, a full refund of
any money paid for a work or a replacement copy, if a defect in
the electronic work is discovered and reported to you within 90
days of receipt of the work.
• You comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.
1.E.9. If you wish to charge a fee or distribute a Project Gutenberg™
electronic work or group of works on different terms than are set
forth in this agreement, you must obtain permission in writing from
the Project Gutenberg Literary Archive Foundation, the manager of
the Project Gutenberg™ trademark. Contact the Foundation as set
forth in Section 3 below.
1.F.
1.F.1. Project Gutenberg volunteers and employees expend
considerable effort to identify, do copyright research on, transcribe
and proofread works not protected by U.S. copyright law in creating
the Project Gutenberg™ collection. Despite these efforts, Project
Gutenberg™ electronic works, and the medium on which they may
be stored, may contain “Defects,” such as, but not limited to,
incomplete, inaccurate or corrupt data, transcription errors, a
copyright or other intellectual property infringement, a defective or
damaged disk or other medium, a computer virus, or computer
codes that damage or cannot be read by your equipment.
1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except for
the “Right of Replacement or Refund” described in paragraph 1.F.3,
the Project Gutenberg Literary Archive Foundation, the owner of the
Project Gutenberg™ trademark, and any other party distributing a
Project Gutenberg™ electronic work under this agreement, disclaim
all liability to you for damages, costs and expenses, including legal
fees. YOU AGREE THAT YOU HAVE NO REMEDIES FOR
NEGLIGENCE, STRICT LIABILITY, BREACH OF WARRANTY OR
BREACH OF CONTRACT EXCEPT THOSE PROVIDED IN PARAGRAPH
1.F.3. YOU AGREE THAT THE FOUNDATION, THE TRADEMARK
OWNER, AND ANY DISTRIBUTOR UNDER THIS AGREEMENT WILL
NOT BE LIABLE TO YOU FOR ACTUAL, DIRECT, INDIRECT,
CONSEQUENTIAL, PUNITIVE OR INCIDENTAL DAMAGES EVEN IF
YOU GIVE NOTICE OF THE POSSIBILITY OF SUCH DAMAGE.
1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you
discover a defect in this electronic work within 90 days of receiving
it, you can receive a refund of the money (if any) you paid for it by
sending a written explanation to the person you received the work
from. If you received the work on a physical medium, you must
return the medium with your written explanation. The person or
entity that provided you with the defective work may elect to provide
a replacement copy in lieu of a refund. If you received the work
electronically, the person or entity providing it to you may choose to
give you a second opportunity to receive the work electronically in
lieu of a refund. If the second copy is also defective, you may
demand a refund in writing without further opportunities to fix the
problem.
1.F.4. Except for the limited right of replacement or refund set forth
in paragraph 1.F.3, this work is provided to you ‘AS-IS’, WITH NO
OTHER WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR ANY PURPOSE.
1.F.5. Some states do not allow disclaimers of certain implied
warranties or the exclusion or limitation of certain types of damages.
If any disclaimer or limitation set forth in this agreement violates the
law of the state applicable to this agreement, the agreement shall be
interpreted to make the maximum disclaimer or limitation permitted
by the applicable state law. The invalidity or unenforceability of any
provision of this agreement shall not void the remaining provisions.
1.F.6. INDEMNITY - You agree to indemnify and hold the Foundation,
the trademark owner, any agent or employee of the Foundation,
anyone providing copies of Project Gutenberg™ electronic works in
accordance with this agreement, and any volunteers associated with
the production, promotion and distribution of Project Gutenberg™
electronic works, harmless from all liability, costs and expenses,
including legal fees, that arise directly or indirectly from any of the
following which you do or cause to occur: (a) distribution of this or
any Project Gutenberg™ work, (b) alteration, modification, or
additions or deletions to any Project Gutenberg™ work, and (c) any
Defect you cause.
Section 2. Information about the Mission
of Project Gutenberg™
Project Gutenberg™ is synonymous with the free distribution of
electronic works in formats readable by the widest variety of
computers including obsolete, old, middle-aged and new computers.
It exists because of the efforts of hundreds of volunteers and
donations from people in all walks of life.
Volunteers and financial support to provide volunteers with the
assistance they need are critical to reaching Project Gutenberg™’s
goals and ensuring that the Project Gutenberg™ collection will
remain freely available for generations to come. In 2001, the Project
Gutenberg Literary Archive Foundation was created to provide a
secure and permanent future for Project Gutenberg™ and future
generations. To learn more about the Project Gutenberg Literary
Archive Foundation and how your efforts and donations can help,
see Sections 3 and 4 and the Foundation information page at
www.gutenberg.org.
Section 3. Information about the Project
Gutenberg Literary Archive Foundation
The Project Gutenberg Literary Archive Foundation is a non-profit
501(c)(3) educational corporation organized under the laws of the
state of Mississippi and granted tax exempt status by the Internal
Revenue Service. The Foundation’s EIN or federal tax identification
number is 64-6221541. Contributions to the Project Gutenberg
Literary Archive Foundation are tax deductible to the full extent
permitted by U.S. federal laws and your state’s laws.
The Foundation’s business office is located at 809 North 1500 West,
Salt Lake City, UT 84116, (801) 596-1887. Email contact links and up
to date contact information can be found at the Foundation’s website
and official page at www.gutenberg.org/contact
Section 4. Information about Donations to
the Project Gutenberg Literary Archive
Foundation
Project Gutenberg™ depends upon and cannot survive without
widespread public support and donations to carry out its mission of
increasing the number of public domain and licensed works that can
be freely distributed in machine-readable form accessible by the
widest array of equipment including outdated equipment. Many
small donations ($1 to $5,000) are particularly important to
maintaining tax exempt status with the IRS.
The Foundation is committed to complying with the laws regulating
charities and charitable donations in all 50 states of the United
States. Compliance requirements are not uniform and it takes a
considerable effort, much paperwork and many fees to meet and
keep up with these requirements. We do not solicit donations in
locations where we have not received written confirmation of
compliance. To SEND DONATIONS or determine the status of
compliance for any particular state visit www.gutenberg.org/donate.
While we cannot and do not solicit contributions from states where
we have not met the solicitation requirements, we know of no
prohibition against accepting unsolicited donations from donors in
such states who approach us with offers to donate.
International donations are gratefully accepted, but we cannot make
any statements concerning tax treatment of donations received from
outside the United States. U.S. laws alone swamp our small staff.
Please check the Project Gutenberg web pages for current donation
methods and addresses. Donations are accepted in a number of
other ways including checks, online payments and credit card
donations. To donate, please visit: www.gutenberg.org/donate.
Section 5. General Information About
Project Gutenberg™ electronic works
Professor Michael S. Hart was the originator of the Project
Gutenberg™ concept of a library of electronic works that could be
freely shared with anyone. For forty years, he produced and
distributed Project Gutenberg™ eBooks with only a loose network of
volunteer support.
Project Gutenberg™ eBooks are often created from several printed
editions, all of which are confirmed as not protected by copyright in
the U.S. unless a copyright notice is included. Thus, we do not
necessarily keep eBooks in compliance with any particular paper
edition.
Most people start at our website which has the main PG search
facility: www.gutenberg.org.
This website includes information about Project Gutenberg™,
including how to make donations to the Project Gutenberg Literary
Archive Foundation, how to help produce our new eBooks, and how
to subscribe to our email newsletter to hear about new eBooks.
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.
More than just a book-buying platform, we strive to be a bridge
connecting you with timeless cultural and intellectual values. With an
elegant, user-friendly interface and a smart search system, you can
quickly find the books that best suit your interests. Additionally,
our special promotions and home delivery services help you save time
and fully enjoy the joy of reading.
Join us on a journey of knowledge exploration, passion nurturing, and
personal growth every day!
ebookbell.com

More Related Content

Similar to Database Programming With Visual Basic Net And Adonet Tips Tutorials And Code 1st Edition Barker (20)

SAP BO ONLINE TRAINING
SAP BO ONLINE TRAININGSAP BO ONLINE TRAINING
SAP BO ONLINE TRAINING
Anusha GOT
 
Certified ASP.Net Programmer
Certified ASP.Net ProgrammerCertified ASP.Net Programmer
Certified ASP.Net Programmer
Narender Rana
 
Asp.net Programmer Certification
Asp.net Programmer CertificationAsp.net Programmer Certification
Asp.net Programmer Certification
Vskills
 
Building & Managing Windows Azure
Building & Managing Windows AzureBuilding & Managing Windows Azure
Building & Managing Windows Azure
K.Mohamed Faizal
 
Building & managing wa app wely
Building & managing wa app   welyBuilding & managing wa app   wely
Building & managing wa app wely
Spiffy
 
Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)
Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)
Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)
crancegaisie
 
Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)
Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)
Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)
anryabrica
 
Sap bo xi r4.0
Sap bo xi r4.0Sap bo xi r4.0
Sap bo xi r4.0
Samatha Kamuni
 
Mastering IDEAScript with Website The Definitive Guide 1st Edition Idea
Mastering IDEAScript with Website The Definitive Guide 1st Edition IdeaMastering IDEAScript with Website The Definitive Guide 1st Edition Idea
Mastering IDEAScript with Website The Definitive Guide 1st Edition Idea
freambloydiy
 
OBIEE Online Training Institute in Hyderabad - C-Point
OBIEE Online Training Institute in Hyderabad - C-PointOBIEE Online Training Institute in Hyderabad - C-Point
OBIEE Online Training Institute in Hyderabad - C-Point
cpointss
 
Visual C 2005 A Developers Notebook Jesse Liberty
Visual C 2005 A Developers Notebook Jesse LibertyVisual C 2005 A Developers Notebook Jesse Liberty
Visual C 2005 A Developers Notebook Jesse Liberty
vayiakhoei
 
Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)
Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)
Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)
moldtkhanizw
 
Oracle ADF Tutorial/Training Study Guide
Oracle ADF Tutorial/Training Study GuideOracle ADF Tutorial/Training Study Guide
Oracle ADF Tutorial/Training Study Guide
Deepak Bhagat
 
Asp.net
Asp.netAsp.net
Asp.net
Rizwan Ahmed
 
Sap business objects bobi training
Sap business objects bobi trainingSap business objects bobi training
Sap business objects bobi training
FuturePoint Technologies
 
Web Development With Sas By Example 2nd Ed Frederick E Pratter
Web Development With Sas By Example 2nd Ed Frederick E PratterWeb Development With Sas By Example 2nd Ed Frederick E Pratter
Web Development With Sas By Example 2nd Ed Frederick E Pratter
eroztiqah
 
SAP BO ONLINE TRAINING
SAP BO ONLINE TRAININGSAP BO ONLINE TRAINING
SAP BO ONLINE TRAINING
Madhukar Reddy
 
Work with data in ASP.NET
Work with data in ASP.NETWork with data in ASP.NET
Work with data in ASP.NET
Peter Gfader
 
visual basic 2005 programmer certification
visual basic 2005 programmer certificationvisual basic 2005 programmer certification
visual basic 2005 programmer certification
Vskills
 
(eBook PDF) Starting Out with C++: Early Objects 9th Edition
(eBook PDF) Starting Out with C++: Early Objects 9th Edition(eBook PDF) Starting Out with C++: Early Objects 9th Edition
(eBook PDF) Starting Out with C++: Early Objects 9th Edition
xltatno
 
SAP BO ONLINE TRAINING
SAP BO ONLINE TRAININGSAP BO ONLINE TRAINING
SAP BO ONLINE TRAINING
Anusha GOT
 
Certified ASP.Net Programmer
Certified ASP.Net ProgrammerCertified ASP.Net Programmer
Certified ASP.Net Programmer
Narender Rana
 
Asp.net Programmer Certification
Asp.net Programmer CertificationAsp.net Programmer Certification
Asp.net Programmer Certification
Vskills
 
Building & Managing Windows Azure
Building & Managing Windows AzureBuilding & Managing Windows Azure
Building & Managing Windows Azure
K.Mohamed Faizal
 
Building & managing wa app wely
Building & managing wa app   welyBuilding & managing wa app   wely
Building & managing wa app wely
Spiffy
 
Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)
Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)
Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)
crancegaisie
 
Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)
Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)
Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)
anryabrica
 
Mastering IDEAScript with Website The Definitive Guide 1st Edition Idea
Mastering IDEAScript with Website The Definitive Guide 1st Edition IdeaMastering IDEAScript with Website The Definitive Guide 1st Edition Idea
Mastering IDEAScript with Website The Definitive Guide 1st Edition Idea
freambloydiy
 
OBIEE Online Training Institute in Hyderabad - C-Point
OBIEE Online Training Institute in Hyderabad - C-PointOBIEE Online Training Institute in Hyderabad - C-Point
OBIEE Online Training Institute in Hyderabad - C-Point
cpointss
 
Visual C 2005 A Developers Notebook Jesse Liberty
Visual C 2005 A Developers Notebook Jesse LibertyVisual C 2005 A Developers Notebook Jesse Liberty
Visual C 2005 A Developers Notebook Jesse Liberty
vayiakhoei
 
Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)
Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)
Starting Out with C++: Early Objects 9th Edition by Tony Gaddis (eBook PDF)
moldtkhanizw
 
Oracle ADF Tutorial/Training Study Guide
Oracle ADF Tutorial/Training Study GuideOracle ADF Tutorial/Training Study Guide
Oracle ADF Tutorial/Training Study Guide
Deepak Bhagat
 
Web Development With Sas By Example 2nd Ed Frederick E Pratter
Web Development With Sas By Example 2nd Ed Frederick E PratterWeb Development With Sas By Example 2nd Ed Frederick E Pratter
Web Development With Sas By Example 2nd Ed Frederick E Pratter
eroztiqah
 
SAP BO ONLINE TRAINING
SAP BO ONLINE TRAININGSAP BO ONLINE TRAINING
SAP BO ONLINE TRAINING
Madhukar Reddy
 
Work with data in ASP.NET
Work with data in ASP.NETWork with data in ASP.NET
Work with data in ASP.NET
Peter Gfader
 
visual basic 2005 programmer certification
visual basic 2005 programmer certificationvisual basic 2005 programmer certification
visual basic 2005 programmer certification
Vskills
 
(eBook PDF) Starting Out with C++: Early Objects 9th Edition
(eBook PDF) Starting Out with C++: Early Objects 9th Edition(eBook PDF) Starting Out with C++: Early Objects 9th Edition
(eBook PDF) Starting Out with C++: Early Objects 9th Edition
xltatno
 

Recently uploaded (20)

Capitol Doctoral Presentation -June 2025.pptx
Capitol Doctoral Presentation -June 2025.pptxCapitol Doctoral Presentation -June 2025.pptx
Capitol Doctoral Presentation -June 2025.pptx
CapitolTechU
 
Analysis of Quantitative Data Parametric and non-parametric tests.pptx
Analysis of Quantitative Data Parametric and non-parametric tests.pptxAnalysis of Quantitative Data Parametric and non-parametric tests.pptx
Analysis of Quantitative Data Parametric and non-parametric tests.pptx
Shrutidhara2
 
BINARY files CSV files JSON files with example.pptx
BINARY files CSV files JSON files with example.pptxBINARY files CSV files JSON files with example.pptx
BINARY files CSV files JSON files with example.pptx
Ramakrishna Reddy Bijjam
 
Ray Dalio How Countries go Broke the Big Cycle
Ray Dalio How Countries go Broke the Big CycleRay Dalio How Countries go Broke the Big Cycle
Ray Dalio How Countries go Broke the Big Cycle
Dadang Solihin
 
Allomorps and word formation.pptx - Google Slides.pdf
Allomorps and word formation.pptx - Google Slides.pdfAllomorps and word formation.pptx - Google Slides.pdf
Allomorps and word formation.pptx - Google Slides.pdf
Abha Pandey
 
Revista digital preescolar en transformación
Revista digital preescolar en transformaciónRevista digital preescolar en transformación
Revista digital preescolar en transformación
guerragallardo26
 
Final Sketch Designs for poster production.pptx
Final Sketch Designs for poster production.pptxFinal Sketch Designs for poster production.pptx
Final Sketch Designs for poster production.pptx
bobby205207
 
How to Manage Inventory Movement in Odoo 18 POS
How to Manage Inventory Movement in Odoo 18 POSHow to Manage Inventory Movement in Odoo 18 POS
How to Manage Inventory Movement in Odoo 18 POS
Celine George
 
How to Manage Upselling of Subscriptions in Odoo 18
How to Manage Upselling of Subscriptions in Odoo 18How to Manage Upselling of Subscriptions in Odoo 18
How to Manage Upselling of Subscriptions in Odoo 18
Celine George
 
Paper 109 | Archetypal Journeys in ‘Interstellar’: Exploring Universal Themes...
Paper 109 | Archetypal Journeys in ‘Interstellar’: Exploring Universal Themes...Paper 109 | Archetypal Journeys in ‘Interstellar’: Exploring Universal Themes...
Paper 109 | Archetypal Journeys in ‘Interstellar’: Exploring Universal Themes...
Rajdeep Bavaliya
 
FEBA Sofia Univercity final diplian v3 GSDG 5.2025.pdf
FEBA Sofia Univercity final diplian v3 GSDG 5.2025.pdfFEBA Sofia Univercity final diplian v3 GSDG 5.2025.pdf
FEBA Sofia Univercity final diplian v3 GSDG 5.2025.pdf
ChristinaFortunova
 
How to Create an Event in Odoo 18 - Odoo 18 Slides
How to Create an Event in Odoo 18 - Odoo 18 SlidesHow to Create an Event in Odoo 18 - Odoo 18 Slides
How to Create an Event in Odoo 18 - Odoo 18 Slides
Celine George
 
LDMMIA Free Reiki Yoga S9 Grad Level Intuition II
LDMMIA Free Reiki Yoga S9 Grad Level Intuition IILDMMIA Free Reiki Yoga S9 Grad Level Intuition II
LDMMIA Free Reiki Yoga S9 Grad Level Intuition II
LDM & Mia eStudios
 
Webcrawler_Mule_AIChain_MuleSoft_Meetup_Hyderabad
Webcrawler_Mule_AIChain_MuleSoft_Meetup_HyderabadWebcrawler_Mule_AIChain_MuleSoft_Meetup_Hyderabad
Webcrawler_Mule_AIChain_MuleSoft_Meetup_Hyderabad
Veera Pallapu
 
Black and White Illustrative Group Project Presentation.pdf (1).pdf
Black and White Illustrative Group Project Presentation.pdf (1).pdfBlack and White Illustrative Group Project Presentation.pdf (1).pdf
Black and White Illustrative Group Project Presentation.pdf (1).pdf
AnnasofiaUrsini
 
What is FIle and explanation of text files.pptx
What is FIle and explanation of text files.pptxWhat is FIle and explanation of text files.pptx
What is FIle and explanation of text files.pptx
Ramakrishna Reddy Bijjam
 
june 10 2025 ppt for madden on art science is over.pptx
june 10 2025 ppt for madden on art science is over.pptxjune 10 2025 ppt for madden on art science is over.pptx
june 10 2025 ppt for madden on art science is over.pptx
roger malina
 
Exploring Ocean Floor Features for Middle School
Exploring Ocean Floor Features for Middle SchoolExploring Ocean Floor Features for Middle School
Exploring Ocean Floor Features for Middle School
Marie
 
The Man In The Back – Exceptional Delaware.pdf
The Man In The Back – Exceptional Delaware.pdfThe Man In The Back – Exceptional Delaware.pdf
The Man In The Back – Exceptional Delaware.pdf
dennisongomezk
 
LDMMIA Spring Ending Guest Grad Student News
LDMMIA Spring Ending Guest Grad Student NewsLDMMIA Spring Ending Guest Grad Student News
LDMMIA Spring Ending Guest Grad Student News
LDM & Mia eStudios
 
Capitol Doctoral Presentation -June 2025.pptx
Capitol Doctoral Presentation -June 2025.pptxCapitol Doctoral Presentation -June 2025.pptx
Capitol Doctoral Presentation -June 2025.pptx
CapitolTechU
 
Analysis of Quantitative Data Parametric and non-parametric tests.pptx
Analysis of Quantitative Data Parametric and non-parametric tests.pptxAnalysis of Quantitative Data Parametric and non-parametric tests.pptx
Analysis of Quantitative Data Parametric and non-parametric tests.pptx
Shrutidhara2
 
BINARY files CSV files JSON files with example.pptx
BINARY files CSV files JSON files with example.pptxBINARY files CSV files JSON files with example.pptx
BINARY files CSV files JSON files with example.pptx
Ramakrishna Reddy Bijjam
 
Ray Dalio How Countries go Broke the Big Cycle
Ray Dalio How Countries go Broke the Big CycleRay Dalio How Countries go Broke the Big Cycle
Ray Dalio How Countries go Broke the Big Cycle
Dadang Solihin
 
Allomorps and word formation.pptx - Google Slides.pdf
Allomorps and word formation.pptx - Google Slides.pdfAllomorps and word formation.pptx - Google Slides.pdf
Allomorps and word formation.pptx - Google Slides.pdf
Abha Pandey
 
Revista digital preescolar en transformación
Revista digital preescolar en transformaciónRevista digital preescolar en transformación
Revista digital preescolar en transformación
guerragallardo26
 
Final Sketch Designs for poster production.pptx
Final Sketch Designs for poster production.pptxFinal Sketch Designs for poster production.pptx
Final Sketch Designs for poster production.pptx
bobby205207
 
How to Manage Inventory Movement in Odoo 18 POS
How to Manage Inventory Movement in Odoo 18 POSHow to Manage Inventory Movement in Odoo 18 POS
How to Manage Inventory Movement in Odoo 18 POS
Celine George
 
How to Manage Upselling of Subscriptions in Odoo 18
How to Manage Upselling of Subscriptions in Odoo 18How to Manage Upselling of Subscriptions in Odoo 18
How to Manage Upselling of Subscriptions in Odoo 18
Celine George
 
Paper 109 | Archetypal Journeys in ‘Interstellar’: Exploring Universal Themes...
Paper 109 | Archetypal Journeys in ‘Interstellar’: Exploring Universal Themes...Paper 109 | Archetypal Journeys in ‘Interstellar’: Exploring Universal Themes...
Paper 109 | Archetypal Journeys in ‘Interstellar’: Exploring Universal Themes...
Rajdeep Bavaliya
 
FEBA Sofia Univercity final diplian v3 GSDG 5.2025.pdf
FEBA Sofia Univercity final diplian v3 GSDG 5.2025.pdfFEBA Sofia Univercity final diplian v3 GSDG 5.2025.pdf
FEBA Sofia Univercity final diplian v3 GSDG 5.2025.pdf
ChristinaFortunova
 
How to Create an Event in Odoo 18 - Odoo 18 Slides
How to Create an Event in Odoo 18 - Odoo 18 SlidesHow to Create an Event in Odoo 18 - Odoo 18 Slides
How to Create an Event in Odoo 18 - Odoo 18 Slides
Celine George
 
LDMMIA Free Reiki Yoga S9 Grad Level Intuition II
LDMMIA Free Reiki Yoga S9 Grad Level Intuition IILDMMIA Free Reiki Yoga S9 Grad Level Intuition II
LDMMIA Free Reiki Yoga S9 Grad Level Intuition II
LDM & Mia eStudios
 
Webcrawler_Mule_AIChain_MuleSoft_Meetup_Hyderabad
Webcrawler_Mule_AIChain_MuleSoft_Meetup_HyderabadWebcrawler_Mule_AIChain_MuleSoft_Meetup_Hyderabad
Webcrawler_Mule_AIChain_MuleSoft_Meetup_Hyderabad
Veera Pallapu
 
Black and White Illustrative Group Project Presentation.pdf (1).pdf
Black and White Illustrative Group Project Presentation.pdf (1).pdfBlack and White Illustrative Group Project Presentation.pdf (1).pdf
Black and White Illustrative Group Project Presentation.pdf (1).pdf
AnnasofiaUrsini
 
What is FIle and explanation of text files.pptx
What is FIle and explanation of text files.pptxWhat is FIle and explanation of text files.pptx
What is FIle and explanation of text files.pptx
Ramakrishna Reddy Bijjam
 
june 10 2025 ppt for madden on art science is over.pptx
june 10 2025 ppt for madden on art science is over.pptxjune 10 2025 ppt for madden on art science is over.pptx
june 10 2025 ppt for madden on art science is over.pptx
roger malina
 
Exploring Ocean Floor Features for Middle School
Exploring Ocean Floor Features for Middle SchoolExploring Ocean Floor Features for Middle School
Exploring Ocean Floor Features for Middle School
Marie
 
The Man In The Back – Exceptional Delaware.pdf
The Man In The Back – Exceptional Delaware.pdfThe Man In The Back – Exceptional Delaware.pdf
The Man In The Back – Exceptional Delaware.pdf
dennisongomezk
 
LDMMIA Spring Ending Guest Grad Student News
LDMMIA Spring Ending Guest Grad Student NewsLDMMIA Spring Ending Guest Grad Student News
LDMMIA Spring Ending Guest Grad Student News
LDM & Mia eStudios
 
Ad

Database Programming With Visual Basic Net And Adonet Tips Tutorials And Code 1st Edition Barker

  • 1. Database Programming With Visual Basic Net And Adonet Tips Tutorials And Code 1st Edition Barker download https://ebookbell.com/product/database-programming-with-visual- basic-net-and-adonet-tips-tutorials-and-code-1st-edition- barker-55142012 Explore and download more ebooks at ebookbell.com
  • 2. Here are some recommended products that we believe you will be interested in. You can click the link to download. Oracle Database Programming With Visual Basicnet Concepts Designs And Implementations Ying Bai https://ebookbell.com/product/oracle-database-programming-with-visual- basicnet-concepts-designs-and-implementations-ying-bai-29341140 Sql Server Database Programming With Visual Basicnet Concepts Designs And Implementations 1 Ying Bai https://ebookbell.com/product/sql-server-database-programming-with- visual-basicnet-concepts-designs-and-implementations-1-ying- bai-11137566 A Guide To The Practical Issues And Applications In Database Programming With Updated Visual Basicnet Murillo https://ebookbell.com/product/a-guide-to-the-practical-issues-and- applications-in-database-programming-with-updated-visual-basicnet- murillo-44123730 Practical Database Programming With Visual Basicnet 2nd Edition 2nd Edition Ying Bai https://ebookbell.com/product/practical-database-programming-with- visual-basicnet-2nd-edition-2nd-edition-ying-bai-36180040
  • 3. Practical Database Programming With Visual Basicnet Ying Bai https://ebookbell.com/product/practical-database-programming-with- visual-basicnet-ying-bai-4105898 Practical Database Programming With Visual Basicnet 1st Edition Ying Bai https://ebookbell.com/product/practical-database-programming-with- visual-basicnet-1st-edition-ying-bai-1367072 Practical Database Programming With Visual Cnet Ying Bai https://ebookbell.com/product/practical-database-programming-with- visual-cnet-ying-bai-47700374 Database Programming With Vbnet Carsten Thomsen Mcse Mcsd Microsoft Mvp Auth https://ebookbell.com/product/database-programming-with-vbnet-carsten- thomsen-mcse-mcsd-microsoft-mvp-auth-4592406 Database Programming With C 1st Edition Carsten Thomsen Auth https://ebookbell.com/product/database-programming-with-c-1st-edition- carsten-thomsen-auth-11852272
  • 5. 1 1.1 Create a Bound List Box 1 1.2 Limit the Data Displayed in a Bound List Box 9 1.3 Bind and View Individual Text Boxes Based Off a Selected List Box Item 13 1.4 Edit and Update Data Using Bound Controls 21 1.5 Add and Delete Records Using Bound Controls 27 1.6 Take Care of Error Handling with Bound Controls 32 1.7 Put the Finishing Touches on a Data Bound Form 37 1.8 Bind Data to ComboBox and DataGrid Controls 42 1.9 Drill Down to Data in the DataGrid Control 46 10.1 Create a Report Using Crystal Reports Report Expert 54 10.2 Display a Report That Was Created 64 10.3 Add Calculated Fields to the Crystal Reports Report 70 10.4 Select Whether the Report Will Be Displayed, Printed, or Exported Using Visual Basic .NET Code 73 10.5 Determine Which Records Will Be Printed at Runtime 80 10.6 Print Labels and Control the Order in Which Records Will Be Printed 85 10.7 Create an Onscreen Report That Contains Hyperlinks 90 11.1 Create Windows NT/2000 Users 94 11.10 Use Object Permissions 99 11.11 Use Fixed Database Roles 102 11.12 Create Custom Database Roles 106 11.13 Create Application Roles 109 11.2 Create Windows NT/2000 Groups 111 11.3 Establish a Windows NT/2000 Authentication Mode 114 11.4 Establish Mixed-Mode Authentication 118 11.5 Create a Standard Login 120 11.6 Create a Windows NT/2000 Login 123 11.7 Use a Fixed Server Role 125 11.8 Create a Database User Account 129 11.9 Use Statement Permissions 132 12.1 Use XMLWriter to Create an XML Document 135 12.2 Use XMLReader to Read an XML Document 143 12.3 Work with the XML Document Object Model 147 12.4 Retrieve XML from SQL Server 2000 154 12.5 Work with Datasets and XML 159
  • 6. 13.1 Get Started with XML Web Services 164 13.2 Create a Simple XML Web Service Using Parameters 172 13.3 Consume XML Web Services 177 13.4 Pass a Dataset Back from an XML Web Service 181 2 2.1 Create a New SQL Server Database from Within Visual Studio .NET 186 2.2 Define Tables and Fields 188 2.3 Define a Primary Key and Other Indexes 193 2.4 Define Relations Between Tables 197 2.5 Define Defaults and Constraints 202 2.6 Create Views 205 2.7 Create Stored Procedures 209 3 3.1 Retrieve Data by Using the DataReader Object 212 3.2 Retrieve Results from SQL Server by Using the DataTable Object 217 3.3 Locate Records with the DataTable Object 219 3.4 Filter and Sort Records Using the DataView Object 223 4 4.1 Edit Data and Update Changes That Are Made to an ADO.NET DataSet Object 229 4.2 Add and Delete Rows in a Dataset with ADO.NET 241 4.3 Execute Parameterized Stored Procedures in ADO.NET 246 4.4 Create and Execute On-the-Fly Batch Updates by Using ADO.NET 249 5 5.1 Use Bound Controls with Web Forms 253 5.2 Validate Data Using Validation Controls 263 5.3 Populate DropDown and ListBox Controls 269 5.4 Display Data Using the Table Control 276 5.5 Display Data Using the Repeater Control 281 5.6 Display, Sort, and Page Data in the DataGrid Control 289 5.7 Add, Edit, and Delete Data Using the DataGrid Control 295 5.8 Hyperlink from a Row in the Data Grid to a Detail Page 306 6 6.1 Retrieve Unique Records Using Only a Select Query 311 6.2 Use Variables and Functions in T-SQL 317 6.3 Use Wildcards and Ranges of Values in a SQL Query 321 6.4 Find Records in a Table Without Corresponding Entries in a Related Table 327
  • 7. 6.5 Take Advantage of Using Subqueries 331 6.6 Create, Modify, and Delete Tables 335 6.7 Create a New Table with Data from Existing Tables 342 6.8 Create and Call SQL Server 2000 User-Defined Functions 346 7 7.1 Create a Dialog Box to Connect to a New Database, Including Listing Available SQL Servers and Databases 353 7.2 Back Up and Verify a SQL Server Database 362 7.3 Restore a SQL Server Database 371 7.4 Transfer Tables Between SQL Server Databases 376 7.5 Create a Detach/Attach SQL Server Database Dialog Box 386 8 8.1 Work with Data-Bound Multi-Select List Boxes Using Windows Forms 394 8.2 Use a Single Windows Form to Update Multiple Lookup Tables 403 8.3 Create a Point-and-Click SQL Server Query Tool for Users Using a Windows Form 409 8.4 Make a Generic Search Form in a Visual Basic .NET Desktop Application 417 8.5 Work with Data-Bound Multi-Select List Boxes Using Web Forms 428 8.6 Use a Single Web Form to Update Multiple Lookup Tables 438 8.7 Create a Point-and-Click Query Tool for Users Using a Web Form 454 8.8 Make a Generic Search Form in an ASP.NET Web Application 462 9 9.1 Define a Class in Visual Basic .NET 472 9.2 Create a Class That Implements the Interface You Defined 478 9.3 Use Visual Studio .NET Tools to Speed Up Writing ADO.NET Code 486 9.4 Control the Creation and Behavior of Classes 499 9.5 Implement the Methods That Update the Database 505 9.6 Validate Data Passed to Properties and Communicate Errors to Developers 514 9.7 Write Data Validation Code That Can Be Reused in Other Classes 520 A About the Author 533 Acknowledgments 534 Appendix A. Desktop Development With ADO 535 C Chapter 1. Developing Windows Forms Using Bound Controls 536 Chapter 10. Creating Reports Using Crystal Reports 537 Chapter 11. Managing SQL Server Security 538 Chapter 12. Utilizing XML Data In Your Visual Basic .NET Applications 539
  • 8. Chapter 13. Creating XML Web Services 540 Chapter 2. Creating SQL Server Database Objects From Visual Studio .NET 542 Chapter 3. Viewing Data With ADO.NET 543 Chapter 4. Manipulating Data With ADO.NET 544 Chapter 5. Working With Data In Web Forms 545 Chapter 6. Creating Transact-SQL Commands 546 Chapter 7. Performing Common Database Tasks Using SQL-DMO 547 Chapter 8. Taking Advantage of Data-Driven Techniques 550 Chapter 9. Using Classes With Databases to Make Life Easier 553 Comments 554 Conclusion 555 Copyright 556 Creating SQL Server Objects with ActiveX Data Objects 558 D Dealing with Stateless Programming 560 Differences Between ADO and ADO.NET 563 E Executing a SQL Server Stored Procedure By Using ActiveX Data Objects 564 Executing Batch Updates with ADO and SQL Server 566 I Index 568 Index A 569 Index B 573 Index C 581 Index D 608 Index E 622 Index F 625 Index G 633 Index H 634 Index I 636 Index J 638 Index K 639 Index L 640 Index M 645 Index N 649 Index O 651
  • 9. Index P 657 Index Q 665 Index R 666 Index S 675 IndexSYMBOL 687 Index T 688 Index U 694 Index V 696 Index W 700 Index X 706 Introduction 709 L Looking At the ADO Object Models 710 Looking at the SQL Server DMF APIs 712 M Main Page 714 O Objects That Are Found in ADO.NET 715 Overview of the XML Web Services Infrastructure 719 R Referencing the Type Libraries 721 S Setting References in .NET for the SQL APIs 723 T Table of content 724 Tell Us What You Think! 728 U Using the 'Connection' Object 729 Utilizing Properties for Tables and Columns 732 W Ways of Utilizing XML in .NET 734 What's Covered in 'Database Programming with Visual Basic .NET and ADO.NET: Tips, Tutorials, and Code'? 735 When to Use ADO (Local Database/Single Tier Applications) 737 Who Is This Book For? 738 Working with Tables, Columns, and Rows 739 Working with the ADO 'Recordset' Object 740
  • 11. [ Team LiB ] 1.1 Create a Bound List Box It used to be that when you wanted to create a data entry form, you just assigned a recordset to the data control and allowed the users to scroll through the data, making changes as needed. When you're dealing with Client Server or Web applications, this just doesn't cut it. One of the first things you need to do is provide a method to limit the amount of data so that users can pick which record they want to edit/view, without pulling all the fields of a table over the Net—either LAN or Internet. List boxes and combo boxes help with that. In this How-To, you will learn how to set up two data controls: OleDbDataAdapter and DataSet. These controls enable you to populate a list box with one line of code. You want to see a list of customers on your Windows form in a ListBox control. You don't want to write code at this point. You only want to prototype a form, so you just want to use bound data controls. How do you create a list box and bind it using the data controls? Technique To get started with learning about any of the objects used for data in .NET, it's important to talk about what .NET Namespaces are and how to use them. Using .NET Namespaces The .NET Framework contains a big class library. This class library consists of a number of Namespaces. These Namespaces are made up of various classes that allow us to create our objects. All of the objects and classes that make up the .NET objects, such as forms, controls, and the various data objects, can be found in Namespaces. Namespaces also can be made up of other Namespaces. For example, there is a Namespace called System.Data. Although this Namespace has classes in it, such as DataSet and DataTable, it also has Namespaces within it called System.Data.OleDb and System.Data.SQLClient, as well as others. To check out the .NET Namespaces, choose Object Browser from the View menu. You can then expand the System.Data Namespace to see the other Namespaces contained within. If you are positive that the database you are going to be working with is SQL Server, then you would be far better served performance-wise to use the classes found in the System.Data.SQLClient Namespace. However, if you are not sure what database you will be working against, you should use the classes found in System.Data.OleDb. For this book, I am using objects created from the classes in the System.Data.OleDb Namespace. That way, you can use the routines against other databases with less modifications. Tip
  • 12. If you know that the back end that you will be accessing is SQL Server, then use the SQL Server type data controls because they are optimized for it. Eight data controls are available for Windows forms. Table 1.1 lists these controls and their uses. You can find these controls by clicking on the Data group in the toolbox. Table 1.1. Data Controls Used in Windows Forms Control Name Purpose DataSet This control is used in conjunction with the other data controls, storing the results that are returned by commands and the DataAdapters. Unlike the recordset from ADO and DAO, the DataSet actually brings back a hierarchical view of the data. Using properties and collections in the DataSet object, you can get all the way down to individual tables, rows, and columns. OleDbDataAdapter This control stores and manages the commands you want to use against an OleDb provider such as Jet, Oracle, or SQL Server. The commands for selecting, updating, inserting, and deleting records can be used. The Connection against which to use the commands is also tracked. OleDbConnection This control maintains connection information for an OleDb provider. This control is used with the OleDbDataAdapter. OleDbCommand Similar to the ADO command object, this control allows you to execute SQL statements or stored procedures to either run bulk operations or return data. SqlDataAdapter This control is the same as the OleDbDataAdapter except that it is for use only against SQL Server stores. SqlConnection This control is the same as the OleDbConnection except that it is for use only against SQL Server stores. SqlCommand This control is the same as the OleDbCommand except that it is for use only against SQL Server stores. DataView This control creates multiple views of the same table. This includes looking at data in various states such as deleted, changed, or sorted differently. Creating two types of the data controls just mentioned, OleDbDataAdapter and DataSet, bind them to a list box to display a list of customers. Note that an OleDbConnection control is also created, but Visual Studio .NET creates it. You then add a line of code to fill the dataset. Steps To preview this How-To, open the solution called VB.Net—Chapter1 found in the chapter folder. When you run the project, the first form that comes up is the main switchboard with each of the How-Tos listed for this chapter. Click on How-To 1.1 to open the form for How-To 1.1 (see Figure 1.1). Figure 1.1. Main form and How-To form 1.1 from the first chapter's solution.
  • 13. Note You can find the source code for all the chapters in the book at www.samspublishing.com. After you are there, just type the book ISBN (0672322471). Create a new Visual Studio .NET project using the Windows Application project template. This creates the initial form called Form1 that you will use. 1. Drag the OleDbDataAdapter control from the Data Controls group located in the toolbox and drop it onto the form. The Data Adapter Configuration Wizard appears. Read the introductory screen, and then click Next to choose your data connection. At this point, if you don't see a data connection to Northwind database in the drop-down list of data connections to use, click the New Connection button. You then see the Data Link Properties dialog box with which you are familiar if you have used other Microsoft products such as Visual Studio 6.0. Type (local) for the server name, select Use Windows NT Integrated Security, and select Northwind for the database (see Figure 1.2.) Click OK. Figure 1.2. From now on, this data connection will show up in Visual Studio .NET's Server Explorer on this machine. 2.
  • 14. Now you will be back on the Choose Your Data Connection page of the Data Adapter Configuration Wizard, with the Northwind database in the Data Connection drop-down list. Click Next. This brings you to the page to select the query type on which the data adapter will be based. Leave the default of Use SQL Statements, and click Next. In the text box that asks What Data Should the Data Adapter Load into the Dataset?, type the following: 3. Select CustomerID, CompanyName From Customers Note By default, the Data Adapter Configuration Wizard creates select statements not only for selecting (viewing) data, but also for inserting, updating, and deleting. If you don't need these other options, click the Advanced Options button at the bottom-left corner of the dialog box. Deselect the check box that reads Generate Insert, Update, and Delete statements. You don't need this because we are just using the data to fill a ListBox control. Click OK to close the Advanced Options dialog box. Click Next to see results of your select statement, as shown in Figure 1.3. If you see something 4.
  • 15. different from Figure 1.3, you either have entered your select statement incorrectly, or you have forgotten to deselect the advanced options. Figure 1.3. Success in creating the data adapter. 4. Click Finished to create a data adapter and connection object. You then see a new data adapter control called OleDbDataAdapter1 and a Connection control called OleDbConnection1. Both controls are in the Components tray below the Form designer. 5. After you have created the first two controls, it is time to create the Dataset object. Right-click on the Data Adapter and choose Generate Dataset from the pop-up menu. This opens the Generate Dataset dialog box. You can keep all the defaults and simply click OK to create a dataset control called DataSet<number>. (The sequential number might vary if you have generated other dataset controls.) 6. Now you are ready to create the ListBox control. Drag the ListBox control from the Windows Forms group in the toolbox and drop it on your form. Stretch the control to the size of your form, and then set the following properties in Table 1.2 on the ListBox control. Table 1.2. ListBox Control Property Settings Needed to Bind a DataSet Control 7. different from Figure 1.3, you either have entered your select statement incorrectly, or you have forgotten to deselect the advanced options. Figure 1.3. Success in creating the data adapter. 4. Click Finished to create a data adapter and connection object. You then see a new data adapter control called OleDbDataAdapter1 and a Connection control called OleDbConnection1. Both controls are in the Components tray below the Form designer. 5. After you have created the first two controls, it is time to create the Dataset object. Right-click on the Data Adapter and choose Generate Dataset from the pop-up menu. This opens the Generate Dataset dialog box. You can keep all the defaults and simply click OK to create a dataset control called DataSet<number>. (The sequential number might vary if you have generated other dataset controls.) 6. Now you are ready to create the ListBox control. Drag the ListBox control from the Windows Forms group in the toolbox and drop it on your form. Stretch the control to the size of your form, and then set the following properties in Table 1.2 on the ListBox control. Table 1.2. ListBox Control Property Settings Needed to Bind a DataSet Control 7.
  • 16. Property Setting DataSource DataSet<Number> DisplayMember Customers.CompanyName ValueMember Customers.CustomerID Although you have bound the dataset to the correct properties in the ListBox control, if you run the form at this point, you will still see a blank ListBox control on the form. Now it is time for the one line of code in this sample, in the Load event of the form. Click on the View Code button in the Solution Explorer, or choose Code from the View menu. In the Code Editor, select (Base Class Objects) from the Class Name drop-down list, and then select Load from the Methods drop-down list. Next, type the line of code as displayed here, which tells the data adapter to fill the dataset with data: 8. OleDbDataAdapter1.Fill(DataSet1) Be sure to use the names of the controls you created. Listing 1.1 presents the Load event code for the form called frmHowTo1_1 in the samples. Listing 1.1 frmHowTo1_1.vb: Filling the Data Set on Which ListBox1 Is Based Private Sub frmHowTo1_1_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Me.OleDbDataAdapter1.Fill(Me.DataSet1) End Sub How It Works When the form called frmHowTo1_1 loads, the Fill method of the OleDbDataAdapter1 is called, with the DataSet1 being passed. Because the DataSource property of ListBox1 was specified as being DataSet1 and the ValueMember and DisplayMember properties are both set appropriately, ListBox1 is populated with the CustomerID and CompanyName from the Customers table in Northwind. Figure 1.4 shows what the final form looks like in Design view, and Figure 1.5 shows what it looks like when running. Figure 1.4. The final design view for your first database how-to.
  • 17. Figure 1.5. This list is based on the Customers table in the Northwind SQL Server database. Comments In the .NET version of Visual Basic, Microsoft went to considerable effort to make the data controls more robust than ever. One cool thing is that most of the tasks that are done for you in Visual Basic .NET are discoverable. Even though you are using the data controls on your form, Visual Studio creates the code under the covers. You can see this code by clicking on the #Region statement that reads like this: #Region " Windows Form Designer generated code "
  • 18. Beware: There is much code here, and you don't want to change it. You can learn a lot from reading it though. As you continue to use the Data Controls shown here, you will become comfortable with changing various properties and getting more power and use out of them. [ Team LiB ]
  • 19. [ Team LiB ] 1.2 Limit the Data Displayed in a Bound List Box Even populating a list box with a couple of columns from a table full of data can be a big performance hit. This How-To shows you how to create a parameterized SQL statement to limit the items that are displayed in the list box, thus giving you better performance on your forms. You have hundreds of thousands of customers in your database, and you don't want the list box loaded up with the whole customer table. How can you limit the data that is displayed in your list box? Technique You are going to make a copy of the form that you created in How-To 1.1. You will then add a Label and TextBox control that the Select statement contained within the OleDbDataAdapter control will query against to limit the data displayed in the list box. A command button will be added to allow you to call the Fill method of the OleDbDataAdapter control whenever you update the text box, and then you can click the command button (see Figure 1.6 ). Figure 1.6. You can now limit the amount of data loaded into the list box. Steps To get started with this How-To, right-click the form you created in How-To 1.1, which should be listed in the Solutions Explorer. Choose Copy from the pop-up menu. Next, right-click the project in the Solution Explorer, and choose Paste from the pop-up menu. You will now have a new Class object in the Solutions Explorer called Copy Of whatever the previous name of the form was . Rename the new form that you have created to the name you desire. Then, with that form highlighted, click on the Code button above the Solutions Explorer. Change the first line of code to say this: Public Class <Name of the new form>
  • 20. You see, VS does not change the line of code automatically for you. It thinks you have a duplicate Class definition. Now you can see that the icon of the form is correct. You can continue with the steps of the How-To. Select the Data Adapter that you created. In the Properties pane, you will see the CommandText property when click on the SelectCommand property plus sign. Replace the CommandText property with the following comman 1. SELECT CustomerID, CompanyName FROM Customers WHERE (CompanyName LIKE ? + '%') You will learn more about the Select statement in Chapter 3 . However, the WHERE clause used here comp CompanyName to a parameter that will be supplied, as indicated by the ?. This will be performed using co the final step of this How-To. The % is a wildcard that tells the server to make it a fuzzy search. Resize the ListBox control, and leave room at the top of the form for the Label, TextBox, and Command button Create these three controls, setting the properties described in Table 1.3 . Label Text Customer TextBox Name txtCustLimit Text A Command Button Name btnLoadList Text Load List Table 1.3. Label, TextBox, and Command Button Control Property Settings Object Property Setting 2. Double-click the new command button you just created called btnLoadList . Enter the code in Listing 1.2 in th 3.
  • 21. Click event of the btnLoadList button. This code loads the data entered from txtCustLimit into the parame of the OleDBDataAdapter1 , which was created by using the ? in the Select statement of the data adapter. T Dataset1 is cleared of its data with the Clear method. Finally, DataSet1 is refilled with data based off the valu txtCustLimit , using the data adapter. Listing 1.2 frmHowTo1_2.vb : Submitting a Parameter to a DataAdapter and Filling the Dataset 3. Private Sub btnLoadList_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnLoadList.Click Me.OleDbDataAdapter1.SelectCommand.Parameters(0).Value = _ Me.txtCustLimit.Text Me.DataSet1.Clear() Me.OleDbDataAdapter1.Fill(Me.DataSet1) End Sub Note There is one big difference here between an OleDbDataAdapter and a SqlDataAdapter . Whereas the OleDbDataAdapter takes a ? to specify a parameter within the Select statement, the SqlDataAdapter requires a named parameter such as @parCustLimit . Therefore, instead of the select statement in step 1 being this: SELECT CustomerID, CompanyName FROM Customers WHERE (CompanyName LIKE ? + '%') It would be this: SELECT CustomerID, CompanyName FROM Customers WHERE (CompanyName LIKE @parCustLimit + '%') The naming of the actual parameter is up to you. Highlight and delete the Load event for the form because you don't want to just fill the event when the form loa You want the user to click btnLoadList . 4. How It Works When the form you created for this How-To loads, or when you're using the form called frmHowTo1_2 , you will see a blank ListBox control with a text box on top with the letter A in it. If you click the command button called btnLoadList , the list box becomes filled with values based on the letter (or letters) in txtCustLimit and on the code described in step 3. Comments
  • 22. Try entering a few other letters, and then try entering no letters. What happens? You limit the list more by the number of letters you enter, and you get all entries when you don't enter any letters. The method displayed here, although simple, is powerful, and it can be used in a variety of ways. You can continue building on this form for the next few How-Tos. If you want to copy your form and start a new one as described at the beginning of the steps for this one, you have the instructions there. Otherwise, by the time you reach How-To 1.8, you will have a data entry form that you can use. Each step, however, is available in the sample solution for this chapter. [ Team LiB ]
  • 23. [ Team LiB ] 1.3 Bind and View Individual Text Boxes Based Off a Selected List Box Item Using a list box similar to the one in the previous How-To, in this How-To, you will learn how to create additional OleDbDataAdapter s and DataSets and bind them to individual text boxes for viewing data. Although the list box is nice for displaying a couple of fields in my form and limiting the rows displayed, how do you list the detail in individual text boxes by clicking on an item in the list box? Technique You are going to enhance the form that you created in How-To 1.2 to use additional data controls, specifically another data adapter and dataset. You will set up the select statement in the new data adapter to take the selected list box item as a parameter. The dataset will then be filled with data, and some text boxes with the dataset set as the data source will display the current record. You can see an example of this in Figure 1.7 . Figure 1.7. You can bind text boxes to datasets as well as list boxes. Steps To go further with the form with which you have been working, you will want to rename the data adapter, dataset, and list box currently on the form to something more meaningful. You can see this in Table 1.4 . ListBox Name ListBox1 lstCustomers
  • 24. OleDbDataAdapter Name OleDbDataAdapter1 odaCustomerList DataSet Name DataSet1 dsCustomerList Table 1.4. Changes to Current Objects on the Form Object Property Old Setting New Setting Tip Name your objects at the time you first create them. This is true of your solutions, projects, and forms, as well as controls used on forms. With the .NET languages being so class and code driven, some items take multiple steps to rename. Visual Studio doesn't seem to catch all the places in code that need to be changed. Renaming a form is a good example. Remember that you had to change the Public Class statement in the code to have it match the new name of the form. Drop another Data Adapter control on the form from the Data group of the toolbox. Use the existing data connection, specify that you will use SQL statements, and assign the following select statement that will use a parameter supplied at runtime by using the selected list box item. 1. SELECT CustomerID, CompanyName, ContactName, ContactTitle, Address, City, Region, PostalCode, Country, Phone, Fax FROM Customers WHERE (CustomerID = ?) You can click the Advanced Options button on the select statement page and deselect creating the Insert, Update, and Delete commands. Finish the Data Adapter Wizard and rename the control odaCustomerIndividual . Right-click odaCustomerIndividual and choose Generate Dataset from the pop-up menu. Create a new dataset called dsCustomerIndividual . Click OK. As of this writing, VS places a 1 at the end of name of the dataset you specified. Clean up the name by removing the 1. Now you should have two data adapters: odaCustomerList and odaCustomerIndividual , and two datasets: dsCustomerList 2. 3.
  • 25. and dsCustomerIndividual . Now it's time to add the text boxes. Resize the form so that it allows you to add a column of text boxes with labels beside them. You will then add the labels and text boxes, setting the Text property of the text boxes to the column names in the Customers table as supplied by dsCustomerIndividual. The Text property of text boxes falls under the Data Binding category in the property sheet. Table 1.5 describes the controls and their property settings. Refer to Figure 1.8 for an example of where to place them. Figure 1.8. Letting users know when they can edit data is helpful. Label Text Customer ID Label Text Company Name Label Text Contact Label Text Contact Title Label Text 3.
  • 27. Name txtContact Text dsCustomerIndividual - Customers.Contact TextBox Name txtContactTitle Text dsCustomerIndividual - Customers.ContactTitle TextBox Name txtAddress Text dsCustomerIndividual - Customers.Address TextBox Name txtCity Text dsCustomerIndividual - Customers.City TextBox Name txtRegion Text dsCustomerIndividual - Customers.Region
  • 28. TextBox Name txtPostalCode Text dsCustomerIndividual - Customers.PostalCode TextBox Name txtCountry Text dsCustomerIndividual - Customers.Country TextBox Name txtPhone Text dsCustomerIndividual - Customers.Phone TextBox Name txtFax Text dsCustomerIndividual - Customers.Fax Table 1.5. New Label and TextBox Control Property Settings for the Form frmHowTo1_3 Object Property Setting Now it's time for the code. To start off, you will change the Click event code for the button called btnLoadList. The first three lines of code are basically the same as in the last How-To, except that the name was changed as needed, and some lines were added to comment the code. 4.
  • 29. Listing 1.3 frmHowTo1_3.vb : Adding the Call to the RefreshIndividual Subroutine 4. Private Sub btnLoadList_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnLoadList.Click '— Store the text entered to limit the list box to the ' data adapter's parameter Me.odaCustomerList.SelectCommand.Parameters(0).Value = _ Me.txtCustLimit.Text '— Clear the current data in the dataset Me.dsCustomerList.Clear() '— Fill the customer list dataset Me.odaCustomerList.Fill(Me.dsCustomerList) '— Fill the initial entry's individual dataset RefreshIndividual() End Sub The only new line of code is the one just before the End Sub , which calls the subroutine RefreshIndividual for the first item in the newly populated list box. This subroutine first handles clearing the dataset called dsCustomerIndividual . It ensures that a customer is chosen in the list box and then places the selected item into the parameter value for odaCustomerIndividual . The dataset called dsCustomerIndividual is then filled, displaying the data in the text boxes bound to the dataset. Listing 1.4 frmHowTo1_3.vb : Refreshing the Dataset on Which the Text Boxes Are Based Private Sub RefreshIndividual() '— Clear individual customer dataset Me.dsCustomerIndividual.Clear() '— Check to see if an item was selected If lstCustomers.SelectedIndex <> -1 Then '— Store the selected customer ID into the ' parameter of the SQL data adapter Me.odaCustomerIndividual.SelectCommand.Parameters(0).Value = _ Me.lstCustomers.SelectedItem(0) '— Fill the dataset Me.odaCustomerIndividual.Fill(Me.dsCustomerIndividual) End If End Sub The only other code is required when a new item is selected in the list box. You want to refresh the text boxes with the new data. This code is on the SelectedIndexChanged event for the
  • 30. lstCustomers list box. Listing 1.5 frmHowTo1_3.vb : Call the RefreshIndividual Routine Private Sub lstCustomers_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles lstCustomers.SelectedIndexChanged '— Fill the current list item's individual dataset RefreshIndividual() End Sub How It Works After the user types a letter into the txtCustLimit text box and clicks btnLoadList , the list box is populated with the items that match the text in the text box. After lstCustomers is populated, the user sees the details for the first item in the list box that is displayed in the text boxes. This occurs within the routine called RefreshIndividual . The selected item is used for the parameter for the data adapter called odaCustomerIndividual , then filling the dataset called dsCustomerIndividual . As the user selects new items in the list box, the data that corresponds to the selected item is displayed. Tip Always try to break your code into specific routines such as the subroutine RefreshIndividual . That way when someone tries to read the code, the code is easy to read, you don't make mistakes by typing the same code two or more times, and you only have to change the code in one place if necessary. Comments Binding text boxes to datasets saves work when switching from one record to another because you don't have to specifically load each text box with data each time. It also gets easier every time you use a data adapter and dataset in combination when manipulating data on your forms. Bound datasets are particularly useful as you edit, add, and delete data on your forms, as you will see in the following How-Tos. [ Team LiB ]
  • 31. [ Team LiB ] 1.4 Edit and Update Data Using Bound Controls Although viewing data is fine in some situations, the real power comes in being able to edit the data in the text box and update the data in the server. In this How-To, you learn just that, using some new methods and properties from the various data controls, including autogenerated commands that create update, insert, and delete SQL statements for you. This How-To also introduces you to the BinderContext class , which is used to perform updates with bound controls. The form as created in How-To 1.4 is great if you just want to view data for various records. But what if you want to let users edit and update the data? Technique Continuing with the form you used in the previous How-Tos, you are going to add a few command buttons with code that will perform the following: Edit. Toggle the look of the text boxes to let the user know that he can edit the data in the controls by giving the controls a sunken look. Save. Save the changes made to the data back to the server. Then toggle the look of the text boxes back to flat so that the user knows he can't edit them. Cancel. Toggle the text boxes back to flat so that the user knows he can't edit them anymore, but don't save the data. It is important to let users know when they can edit and when they can't. By toggling the style of the text boxes between flat and sunken and the color between gray and white, users have a definite clue that they can edit the data at certain times (see Figure 1.8 ). Another useful item to note about this How-To is the introduction of the BindingContext class. This class helps you work with data bound controls. Each control on a Windows form has a BindingContext object as well as BindingContext objects for any controls that are contained within that control. Each form also has a BindingContext object. BindingContext objects manage BindingManagerBase class object(s) for each control. Through the BindingContext object, you can manage editing and updating data back to the server. BindingManagerBase objects help with synchronization of datasets with controls. You are going to use the BindingContext class throughout the rest of this chapter, but only a couple of methods. Steps Open the solution for the chapter called "VB .NET How-To Chapter 1 ," and run the application. From the main form, click the command button with the caption "How-To 1.4." Click the Load List button . Along with the list being filled with customers whose names start with A , you will see the detail How-To fill in on the right side of the form with the first customer in the list. Click Edit. You will now be able to change the data in the text boxes. After you have changed a couple of fields, click Save. If you select another customer from the list box, select the one you changed. You will see that your changes have in fact been saved. If you click Cancel instead of Save, your changes will not be saved. Note that if you change the name of the customer, you must load the list again to see the changes in the list box. Add the three command buttons to your form as described in Table 1.6 and as displayed in Figure 1.8 . 1.
  • 32. Command Button Name btnEdit Caption &Edit Command Button Name btnSave Caption &Save Command Button Name btnCancel Caption &Cancel Table 1.6. Command Buttons to Edit, Save, and Cancel Changes to Data Object Property Setting 1. Add the code shown in Listing 1.6 to the btnEdit Click event. Listing 1.6 frmHowTo1_4.vb : Calling the ActiveEditing Subroutine from the btnEdit Command Button 2. 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
  • 33. This calls the routine called ActivateEditing , listed here. This code iterates through all the controls on the form and uses the TypeOf condition to check whether the current control is a text box. It also ensures that the control is not the txtCustLimit text box. If the control is a text box and the parameter called bEnable has been passed in as True , then the sunken look is given to the text box using the BorderStyle and the BackColor property is set to white. Otherwise, the BorderStyle is set to FixedSingle , which is flat, and the BackColor is set to the backcolor of the form. The Enabled property of the text box is set to whatever bEnabled is: True or False . Listing 1.7 frmHowTo1_4.vb : Toggling the Enabled Property and Look of Text Boxes 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 Add the code to the Click event of the btnSave command button. This code calls a new routine called SaveRecord , which performs the actual save. The ActivateEditing is then called, passing False to disable the controls because you are finished editing. Listing 1.8 frmHowTo1_4.vb : Calling the SaveRecord Routine and Disabling the Text Boxes by Calling ActivateEditing 3.
  • 34. 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 Following is the code for the subroutine called SaveRecord . This routine calls the EndCurrentEdit method of the BindingContext class, passing in the dataset called dsCustomerIndividual , and specifying the Customers table. Then the Update method is called off the data adapter called odaCustomerIndividual , passing the same parameters. This updates the changes back to the dataset Finally, the dataset changes are sent back to the server. Listing 1.9 frmHowTo1_4.vb : Saving the Data Back to the Server Private Sub SaveRecord() '— Use the BindingContext class to end current editing ' so that we can update the server. Me.BindingContext(Me.dsCustomerIndividual, "Customers").EndCurrentEdit() '— Perform the requested task at the dataset ' level using the data adapter Me.odaCustomerIndividual.Update(Me.dsCustomerIndividual, "Customers") '— By accepting the changes, the data gets sent back to the server Me.dsCustomerIndividual.AcceptChanges() End Sub Note If you haven't read about ADO.NET yet, then you might be confused about doing an update to the dataset, accepting changes, and sending the changes back to the server. ADO.NET works using disconnected data. When you create a dataset by using a data adapter, the data is actually created using XML. To see proof of this, take a look at dsCustomerIndividual.xsd, found in the Solutions Explorer. <xsd:schemaid="dsCustomerIndividual"targetNamespace="http://www.tempuri.org / dsCustomerIndividual.xsd"xmlns="http://www.tempuri.org/ dsCustomerIndividual.xsd"xmlns: xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com: xml-msdata"attributeFormDefault="qualified" elementFormDefault="qualified"> <xsd:element name="dsCustomerIndividual" msdata:IsDataSet="true"> <xsd:complexType> <xsd:choice maxOccurs="unbounded">
  • 35. <xsd:element name="Customers"> <xsd:complexType> <xsd:sequence> <xsd:element name="CustomerID" type="xsd:string" /> <xsd:element name="CompanyName" type="xsd:string" /> <xsd:element name="ContactName" type="xsd:string" minOccurs="0" /> <xsd:element name="ContactTitle" type="xsd:string" minOccurs="0" /> <xsd:element name="Address" type="xsd:string" minOccurs="0" /> <xsd:element name="City" type="xsd:string" minOccurs="0" /> <xsd:element name="Region" type="xsd:string" minOccurs="0" /> <xsd:element name="PostalCode" type="xsd:string" minOccurs="0" /> <xsd:element name="Country" type="xsd:string" minOccurs="0" /> <xsd:element name="Phone" type="xsd:string" minOccurs="0" /> <xsd:element name="Fax" type="xsd:string" minOccurs="0" /> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:choice> </xsd:complexType> <xsd:unique name="Constraint1" msdata:PrimaryKey="true"> <xsd:selector xpath=".//Customers" /> <xsd:field xpath="CustomerID" /> </xsd:unique> </xsd:element> </xsd:schema> This is all performed under the covers, so the good news is that you don't have to know XML to work with datasets and ADO. More information on this can be found in Chapter 3 . The last task is to give you the capibility to cancel the edits. You do this by placing the following code in the Click event on btnCancel . Calling the CancelCurrentEdit method of the BindingContext object for the form, the current edits are cancelled. Next, the text boxes are disabled using the routine ActivateEditing. Listing 1.10 frmHowTo1_4.vb : Canceling Changes to Data and Disabling the Text Boxes Again 4. 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. Me.BindingContext(Me.dsCustomerIndividual, _ "Customers").CancelCurrentEdit() ActivateEditing(False) End Sub How It Works When the user clicks the btnEdit button, the ActiveEditing routine alerts the user that he can edit the data in the text boxes. The text boxes are enabled.
  • 36. If the user then clicks the btnSave button, the data is updated to the dataset and then back to the server. If the user clicks the btnCancel button, the edits are canceled. In both cases, the ActivateEditing routine is called to disable the text boxes and let the user know that the text boxes cannot be edited. Comments This How-To showed the bare bones for editing and updating data. It presented a basic technique to get started. As you continue, you will learn methods to add and delete records, as well as handle errors. Using ADO.NET, which you use for bound controls, takes some getting used to if you have worked with other data accessing methods such as ADO and DAO. The BindingContext and BindingManagerBase objects make working with bound objects in code much more manageable. [ Team LiB ]
  • 37. [ Team LiB ] 1.5 Add and Delete Records Using Bound Controls Besides editing data, adding new records and deleting records in a table are obviously important features. This How-To shows you just that, taking advantage of the BinderContext class. Besides being able to edit current records that already exist, users need to be able to add and delete records as well. How do you add and delete records using bound controls? Technique To create the Add New Record feature, you will add a button called btnAddNew that has code behind it. You will use the BindingContext object again to add a new record by using the AddNew method . A module variable will be added to the form to keep track of whether a record is being added or edited. If a new record is being added, then when the update is performed, the application needs to reload the data in the list box in case the new record's CompanyName data falls into the chosen list limit that is specified in the txtCustLimit text box. To create the Delete Record feature, you will add a button called btnDelete . This button will have code behind it that will use the RemoveAt method of the ContextBinding object to remove the record from the dataset. The data will then be posted back to the server. Steps Open the solution for the chapter called "VB .NET How-To Chapter 1 ," and run the application. From the main form, click on the command button labeled How-To 1.5. Click the Load List button . Click the button labeled New. Enter the text ALF for Customer ID and Alfred's Fried Foods in the Company Name. Then click the button labeled Save, and see the record you just entered added to the list. After the record has been entered, you can test the delete feature by clicking on the button named Delete. The record goes away, and the list is rebuilt. Add a new command button under btnEdit , and then set the Name property to btnNew and the Caption property to &Save . 1. Add a new module-level variable called mbAddNew , which is a Boolean variable to keep track of whether you are adding a new record. This variable will be placed outside of your routines, just under the forms code. You can see this in Figure 1.9 . Figure 1.9. By placing this variable just underneath Windows Form Designer Generated Code and declaring it Private, routines inside the Class can see it, but those outside cannot. 2.
  • 38. Tip You can collapse and expand routines that you are working on within modules. This makes it handy when you are working on new routines (which can be expanded) and don't want to mess with old routines (which can be collapsed). Add the following code to the Click event of the new command button btnNew . This code first sets the Boolean variable called mbAddNew to True . It then uses the AddNew method of the form's BindingContext object to add a new record to the dsCustomerIndividual dataset. Finally, the code calls the ActiveEditing routine to enable the text boxes. Listing 1.11 frmHowTo1_5.vb : Adding a New Record to the dsCustomerIndividual Dataset and Toggling Text Boxes 3. Private Sub btnNew_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnNew.Click mbAddNew = True '— Using the BindingContext class add a new record Me.BindingContext(Me.dsCustomerIndividual, "Customers").AddNew() ActivateEditing(True)
  • 39. End Sub Modify the Click event of the btnSave to test whether the mbAddNew flag has been set to True , meaning that a new record is being added. If True , then after saving the record by calling the SaveRecord and ActivateEditing routines, the LoadList and RefreshIndividual are called to load the new record's data. Note that the SaveRecord, ActiveEditing , and RefreshIndividual routines have not changed from How-To 1.4. The mbAddNew variable is then set to False . Listing 1.12 frmHowTo1_5.vb : Saving the Changed Data, Toggling Text Boxes, and Reloading the List Box and First Record in the List 4. 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) If mbAddNew Then LoadList() RefreshIndividual() mbAddNew = False End If End Sub Modify the Click event for the btnCancel button to reset the mbAddNew variable to False , as seen in Listing 1.13 . Listing 1.13 frmHowTo1_5.vb : Canceling the Edit and Resetting the mbAddNew Variable 5. 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. Me.BindingContext(Me.dsCustomerIndividual, "Customers").CancelCurrentEdit() ActivateEditing(False) mbAddNew = False End Sub Now it is time to add the delete functionality. To do this, add the following code to the Click event of the new button called btnDelete . The first line of the code you added begins by introducing a new method called RemoveAt and a new property called Position, both used with the BindingContext 6.
  • 40. object. You will work from the inside out. The Position property tracks the current position in the dataset, in this case dsCustomerIndividual. The RemoveAt method marks the record that is at the position passed to it for deletion. Next, the Update method of the odaCustomerIndividual adapter is used to call the DELETE SQL statement command against the dataset, deleting the actual rows in the data set. The AcceptChanges method is called to send the changes to the dataset, a delete in this case, back to the server. Finally, the LoadList , RefreshIndividual , and ActivateEditing subroutines are called to refresh the list, refresh the first record in the list for the text boxes, and toggle the text boxes so that the user knows he can't edit them. Listing 1.14 frmHowTo1_5.vb : Deleting the Selected Record and Reloading the List Box 6. Private Sub btnDelete_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnDelete.Click '— Mark the row for deletion using the RemoveAt method of the BindingContext Me.BindingContext(Me.dsCustomerIndividual, _ "Customers").RemoveAt(Me.BindingContext(Me.dsCustomerIndividual, "Customers").Position) '— Perform the requested task at the dataset ' level using the data adapter odaCustomerIndividual.Update(dsCustomerIndividual, "Customers") '— By accepting the changes, the data gets sent back to the server dsCustomerIndividual.AcceptChanges() '— Reload the list LoadList() '— Display the first record RefreshIndividual() '— Disable the text boxes ActivateEditing(False) End Sub How It Works When the user clicks the btnNew button, a flag (mbAddNew ) is set to True , the dataset is set for adding a record with the AddNew method of the BindingContext , and the text boxes are enabled for editing. If the user then clicks the btnSave button, the data is updated to the dataset and then back to the server. If the user clicks the btnCancel button, the edits are canceled. In both cases, the mbAddNew variable is set to False and the ActivateEditing routine is called to disable the text boxes and let the user know that the text boxes are not available for editing. Finally, if the btnSave button was clicked and the mbAddNew was set to True , the LoadList and RefreshIndividual routines are called. When the user clicks the btnDelete button, the record is deleted from the recordset and then from the server. The list box is reloaded and the first record in the list is displayed in the text boxes. The text boxes are then disabled.
  • 41. Comments Here you have the basic commands needed to create a full-fledged data entry form. You can add, edit, and delete information from the form. This actually takes less code than if you use Visual Basic 6.0. The BindingContext object really goes a long way to helping you work with bound data. [ Team LiB ]
  • 42. [ Team LiB ] 1.6 Take Care of Error Handling with Bound Controls When dealing with database tasks, you are going to get runtime errors. In .NET, we call the various types of errors you can get exceptions. This How-To shows examples of what exceptions could occur and how to handle them using the Try, Catch, and Finally statements. Adding and deleting records is fine, but what happens if an error occurs? You tried to delete an existing company, and got the screen that appears in Figure 1.10. Figure 1.10. This is an unhandled error, called an exception in .NET. How do you make it so errors are handled gracefully within the application using bound controls? Technique Error handling is one of the most important aspects of working with data, between when a user is entering data and updating the server. If you don't have proper error handling, your system will, in the best situation, give an ugly error message, and in the worst, blow up and put bad data in your system. In Visual Studio .NET, errors are classes called exceptions. Many different (inherited) types of exceptions exist. Run-time exceptions can occur in just about any part of your application. They can be handled by using Try...Catch...Finally or they can be unhandled, where you will see the error in Figure 1.11. Figure 1.11. This error was thrown up from one subroutine to the one that called it. Take a look at a common way to trap exceptions shown in Listing 1.15. Listing 1.15 Standard Code for Handling Exceptions
  • 43. Private Sub MySub() Try '—Code to be handled here Catch dataException as Exception MessageBox.Show(dataException.Message) Finally '—Code that will occur regardless of if an error occurs. End Try End Sub Following are some basic points to help you when working with exceptions and Try...Catch...Finally blocks: The name of the exception object can be whatever you want it to be. dataException was just used as an example. Specific types of exceptions inherit from the base class of System.Exception. OleDbException is one of those classes, and you will see an example of using this class in the following steps. You can use the Throw statement within a Catch statement to throw the exception back up to a calling subroutine. You can use the When clause on the Catch statement to trap for specific exceptions. When multiple Catch statements are used, each one is executed unless an End Try or End Sub is placed within a Catch block, as in this How-To. You can use multiple Catch statements to handle various possible exceptions that can occur. You will see an example of these bullets in the following steps. Steps Taking the form with which you have been working, you are going to modify it to trap exceptions when the record is being saved (either for additions or editing) and when the record is deleted. You will also add some code in the event when closing the form. Modify the code in the Click event of the command button called btnSave. You will surround the SaveRecord routine call with a Try...Catch...End Try block. If an exception occurs, the Show method of the MessageBox class is called, passing the Message property of the Exception object called saveException. Next, the subroutine is exited. If no errors occur, then life goes on, and so does the subroutine. 1.
  • 44. Listing 1.16 frmHowTo1_6.vb: Code Added to btnSave Click Event to Trap Save Exceptions Private Sub btnSave_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnSave.Click Try '— Save the information SaveRecord() Catch saveException As Exception MessageBox.Show("The following error has occurred: " & _ saveException.Message, "Error Saving Record") Exit Sub End Try '— Disable the text boxes ActivateEditing(False) If mbAddNew Then LoadList() RefreshIndividual() mbAddNew = False End If End Sub Modify the SaveRecord routine to "throw" the exception up to the btnSave_Click subroutine, or whatever happens to have called the SaveRecord routine. Following is the SaveRecord subroutine with the new Try...Catch...End Try block added, along with the Throw statement. Listing 1.17 frmHowTo1_6.vb: Pass the Exception Back Up to the Calling Routine 2. Private Sub SaveRecord() Try '— Use the BindingContext class to end the current editing so ' that we can update the server. Me.BindingContext(Me.dsCustomerIndividual, _ "Customers").EndCurrentEdit() '— Perform the requested task at the dataset ' level using the data adapter odaCustomerIndividual.Update(dsCustomerIndividual, "Customers") '— By accepting the changes, the data gets sent back to the server dsCustomerIndividual.AcceptChanges()
  • 45. Catch saveException As Exception Throw saveException End Try End Sub Now it's time to deal with adding exception handling to the btnDelete Click event, as seen next. The Try statement is used to wrap the code that performs deletion of the data. The code then uses a Catch statement to check whether the exception that occurs is a specific OleDbException, 3621, which is an error having to do with trying to delete a record when related records exist in another table. Note that you could—and in fact should—assign this to a constant value. Because delException has been caught as an OleDbException, you can look at the NativeError property of the first error in the Errors collection to get the actual OleDb error number. If the error is not 3621, then the exception is trapped with the next Catch statement, and a messagebox is displayed. If errors occur, then the subroutine is exited before the final lines of code are executed. Listing 1.18 frmHowTo1_6.vb: Catching Exceptions When You're Deleting a Record 3. Private Sub btnDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDelete.Click Try '— Mark the row for deletion using the RemoveAt ' method of the BindingContext Me.BindingContext(Me.dsCustomerIndividual, "Customers").RemoveAt(Me.BindingContext(Me.dsCustomerIndividual, "Customers").Position) '— Perform the requested task at the dataset ' level using the data adapter odaCustomerIndividual.Update(dsCustomerIndividual, "Customers") '— By accepting the changes, the data gets sent back to the server dsCustomerIndividual.AcceptChanges() Catch delException As System.Data.OleDb.OleDbException _ When delException.Errors(0).NativeError = 3621 MessageBox.Show("An error occurred because of related order records.", "Error Deleting Customer", _ MessageBoxButtons.OK, MessageBoxIcon.Exclamation) Exit Sub Catch delException As Exception MessageBox.Show(delException.Message, "Error Deleting Customer", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) Exit Sub End Try
  • 46. '— Reload the list LoadList() '— Display the first record RefreshIndividual() '— Disable the text boxes ActivateEditing(False) End Sub How It Works When an exception occurs within the Try...Catch...End Try block, the Catch statements are compared when a When clause is used or when the code is simply executed. If a Throw statement is used, then an execution is thrown back up a level to the Try...Catch...End Try block containing the call to the routine where the Throw statement occurred. You can see an example of this in Figure 1.11. Comments Microsoft has gone to great length to let you control how you handle exceptions in .NET with the various languages. You can be as creative as you need to by using the Try...Catch...End Try block with all the clauses available. Exceptions bring back plenty of information so that you can create pretty slick error handling. You can use exceptions to create a centralized routine that logs errors, or even one that e-mails exception information to you from your applications. [ Team LiB ]
  • 47. [ Team LiB ] 1.7 Put the Finishing Touches on a Data Bound Form Besides handling the basics, you need to add some finishing touches to a data entry form, such as enabling/disabling controls based on whether you're on a record. This How-To shows you how to use the Enabled properties on controls to give the user more direction when using a Windows form (see Figure 1.12 ). Figure 1.12. You will create this complete form by How-To 1.7, with all the bells and whistles that users expect from a good data entry form. Although the majority of the major issues are taken care of for the form you created so far in the chapter, your users become confused about when to push some of the buttons. How do you get the buttons to reflect when the users can click them, and what other finishing touches might help the form? Technique An important part of user interfaces is letting the user know when he has access to certain features on the form. In this case, you will see how to do the following: Toggle the enabled property of the btnSave , btnCancel , btnNew , and btnDelete at the appropriate moments, such as when a record is highlighted in the list box. Add a command button to close the form. Add code to the Closing event of the form that tests whether you have made changes to the current record, and if so, whether you want to save the changes. You can see an example of particular command buttons being enabled based on the current action being performed in the form in Figure 1.13 . Figure 1.13. This form allows users to access command buttons only when the functionality is
  • 48. available. Steps Continuing on with the form that you have been using, you are going to make the changes just mentioned in the previous bulleted list. Start by modifying two routines already created: RefreshIndividual and ActivateEditing subroutines. Then check whether a customer has been selected in lstCustomers . If not, then the two buttons, btnEdit and btnDelete, are disabled. If a customer hasn't been selected, the two buttons are enabled, and the dsCustomerIndividual dataset control is refreshed. Listing 1.19 frmHowTo1_7.vb : Toggling the Enabled Property of the btnEdit and btnDelete Buttons 1. Private Sub RefreshIndividual() '— Clear individual customer dataset Me.dsCustomerIndividual.Clear() If lstCustomers.SelectedIndex = -1 Then btnEdit.Enabled = False btnDelete.Enabled = False Else btnEdit.Enabled = True btnDelete.Enabled = True Me.odaCustomerIndividual.SelectCommand.Parameters(0).Value = lstCustomers.SelectedItem(0) '— Fill the dataset Me.odaCustomerIndividual.Fill(Me.dsCustomerIndividual, "Customers") End If
  • 49. End Sub Similarly, you will add code to the ActivateEditing subroutine to toggle the Enable property of the various command buttons, depending on their purpose. Listing 1.20 shows the entire routine. Listing 1.20 frmHowTo1_7.vb : Toggling the Enabled Property of btnEdit and btnDelete Buttons 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 '— Enable/Disable the appropriate buttons btnEdit.Enabled = Not bEnable btnNew.Enabled = Not bEnable btnDelete.Enabled = Not bEnable btnCancel.Enabled = bEnable btnSave.Enabled = bEnable '— Set the focus to the CustomerID text box If bEnable Then Me.txtCustomerID.Focus() End If End Sub
  • 50. The specific lines of code added are shown here: '— Enable/Disable the appropriate buttons btnEdit.Enabled = Not bEnable btnNew.Enabled = Not bEnable btnDelete.Enabled = Not bEnable btnCancel.Enabled = bEnable btnSave.Enabled = bEnable These buttons are handled as the other buttons are—by taking the opposite value to which bEnable is currently set, and using it to toggle the Enabled property. Finally, if the bEnable flag is True , then focus is moved to the txtCustomerID text box using the following lines of code: '— Set the focus to the CustomerID text box If bEnable Then Me.txtCustomerID.Focus() End If End Sub Add a new command button, with the properties Name and Text set to btnClose and &Close , respectively. Place the code in Listing 1.21 for the Click event. Listing 1.21 frmHowTo1_7.vb : Close the Form 2. Private Sub btnClose_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnClose.Click Me.Close() End Sub Add some code to the Closing event of the form. Listing 1.22 tests whether the btnSave button is enabled. If it is, the MessageBox method is evoked, asking the user if he wants to save changes that were made. If so, then the SaveRecord is called within a Try...Catch...End Try block. Listing 1.22 frmHowTo1_7.vb : Checking Whether the User Wants to Save a Record Before Closing 3. Private Sub frmHowTo1_7_Closing(ByVal sender As Object, _ ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing '— If an edit or add has been requested, enabling the Save button, ' then prompt to save the record
  • 51. If btnSave.Enabled Then If MessageBox.Show("Would you like to save the current record?", _ "Save Record?", MessageBoxButtons.YesNo) = _ DialogResult.Yes Then Try '— Save the information SaveRecord() Catch saveException As Exception If MessageBox.Show("The following error has occurred: " & saveException.Message & vbCrLf & vbCrLf & _ "Continue with closing the form?", "Error Saving Record", MessageBoxButtons.YesNo) = DialogResult.No Then e.Cancel = True End If End Try End If End If End Sub How It Works In the modifications made to the form in this How-To, many things happen depending on what is occurring. When the user clicks the btnEdi t button, btnEdit , btnNew , and btnDelete are disabled, and btnCancel and btnSave are enabled. The opposite is true when btnCancel and btnSave are pressed. If bEnable is True , then the focus is moved to the txtCustomerID text box. When the txtClosed button is clicked, the application then checks whether the btnSave command button has been enabled, meaning data is being edited. If so, then the user is asked whether he wants to save the current record. If the user does, the system then saves the current information back to the server. Comments The tasks displayed in this How-To are just a few of the tasks you can do to make your forms look and feel more professional. They are also what users come to expect from database applications. Play with the form a bit more. You're sure to come up with a few more ideas. [ Team LiB ]
  • 52. [ Team LiB ] 1.8 Bind Data to ComboBox and DataGrid Controls Sometimes you might want to use a ComboBox control instead of a ListBox control to display a list of choices. You also might want to display information in a grid style based on the item chosen in that combo box. This How-To describes how to bind data to both ComboBox and DataGrid controls. Instead of using a ListBox control to display customers, you would like to use a ComboBox control to display them. After you choose a customer, you would like to display information about the orders that belong to that customer. How do you bind data to the ComboBox and then bind the DataGrid control as well? Technique To bind both the ComboBox and the DataGrid controls, you will use the same properties and coding techniques that you have used for the ListBox control. You will first create DataAdapter and DataSet controls to which to set the DataSource properties. The DataAdapter for the DataGrid will include a parameter that will use the value selected in the ComboBox control. You will set the DataSource properties of the controls to the DataSet created. That is all you really have to set for the DataGrid control. For the ComboBox control, you will also set the ValueMember and DisplayMember properties. You will then add code to fill the DataSet control to which the DataSource property is set for the ComboBox control. Finally, you will create a subroutine to store the selected value in the ComboBox in the DataAdapter that was created for filling the DataSet on which the DataGrid control is based. After the user has selected a value in the ComboBox that contains the customers, the DataGrid control displays the orders for that customer, as can be seen in Figure 1.14. Figure 1.14. Users can display the header information for customer orders using these two controls.
  • 53. Steps You will be starting with a fresh form. Add a new Windows Form called frmHowTo1_8. 1. Add the OleDbDataAdapter and DataSet controls with the properties set forth in Table 1.7. Table 1.7. OleDataAdapter and DataSet Controls Object Property Setting OleDataAdapter Name odaCustomerList SelectCommand OleDbSelectCommand1 CommandText SELECT CustomerID, CompanyName FROM Customers DataSet Name dsCustomerList DataSetName dsCustomerList OleDataAdapter Name odaOrdersForCustomer SelectCommand OleDbSelectCommand2 CommandText SELECT OrderID, OrderDate, RequiredDate, ShippedDate FROM Orders WHERE (CustomerID = ? ) ORDER BY OrderDate DataSet Name dsOrdersForCustomer DataSetName dsOrdersForCustomer Tip You will want to create the OleDbDataAdapter controls using the Data Adapter Configuration Wizard, and then set the name after the DataAdapter has been created. You will want to create the DataSet controls by right-clicking on the appropriate OleDbDataAdapter and choosing Generate Dataset. If you have questions about creating these controls, reread How-To 1.1. Also, remember that when generating the DataSet, VS always changes the name by adding a 1 on the end and capitalizing the first letter. You might want to change it to what you really want in the properties directly. 2. Add the ComboBox and DataGrid controls, as well as the Label for the ComboBox, setting the properties as shown in Table 1.8. 3.
  • 54. Table 1.8. Label, ComboBox, and DataGrid Controls Property Settings Object Property Setting Label Name Label1 Text "Customers to List Orders For:" ComboBox Name cboCustomers DataSource dsCustomerList.Customers DisplayMember CompanyName ValueMember CustomerID DataGrid Name dgOrders DataSource dgOrdersForCustomer.Orders Add code shown in Listing 1.23 to the Load event of the form. This code fills the dsCustomerList DataSet control based off the select statement used in the odaCustomerList OleDbDataAdapter control. After this occurs, the RefreshOrders subroutine is called, displayed in Listing 1.24. Listing 1.23 frmHowTo1_8.vb: Filling the Dataset Used by the ComboBox Control 4. Private Sub frmHowTo1_8_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Me.odaCustomerList.Fill(Me.dsCustomerList) RefreshOrders() End Sub Listing 1.24 frmHowTo1_8.vb: Filling the Dataset Used by the DataGrid Control, Based on the Item Selected in the ComboBox Control Private Sub RefreshOrders() '— Clear Orders for customer dataset Me.dsOrdersForCustomer.Clear() '— Check to see if an item was selected If Me.cboCustomers.SelectedIndex <> -1 Then '— Store the selected customer ID into the parameter ' the SQL data adapter Me.odaOrdersForCustomer.SelectCommand.Parameters(0).Value = _ Me.cboCustomers.SelectedItem(0) '— Fill the dataset Me.odaOrdersForCustomer.Fill(Me.dsOrdersForCustomer) End If End Sub 5.
  • 55. Random documents with unrelated content Scribd suggests to you:
  • 56. This eBook is for the use of anyone anywhere in the United States and most other parts of the world at no cost and with almost no restrictions whatsoever. You may copy it, give it away or re-use it under the terms of the Project Gutenberg License included with this eBook or online at www.gutenberg.org. If you are not located in the United States, you will have to check the laws of the country where you are located before using this eBook. 1.E.2. If an individual Project Gutenberg™ electronic work is derived from texts not protected by U.S. copyright law (does not contain a notice indicating that it is posted with permission of the copyright holder), the work can be copied and distributed to anyone in the United States without paying any fees or charges. If you are redistributing or providing access to a work with the phrase “Project Gutenberg” associated with or appearing on the work, you must comply either with the requirements of paragraphs 1.E.1 through 1.E.7 or obtain permission for the use of the work and the Project Gutenberg™ trademark as set forth in paragraphs 1.E.8 or 1.E.9. 1.E.3. If an individual Project Gutenberg™ electronic work is posted with the permission of the copyright holder, your use and distribution must comply with both paragraphs 1.E.1 through 1.E.7 and any additional terms imposed by the copyright holder. Additional terms will be linked to the Project Gutenberg™ License for all works posted with the permission of the copyright holder found at the beginning of this work. 1.E.4. Do not unlink or detach or remove the full Project Gutenberg™ License terms from this work, or any files containing a part of this work or any other work associated with Project Gutenberg™. 1.E.5. Do not copy, display, perform, distribute or redistribute this electronic work, or any part of this electronic work, without prominently displaying the sentence set forth in paragraph 1.E.1
  • 57. with active links or immediate access to the full terms of the Project Gutenberg™ License. 1.E.6. You may convert to and distribute this work in any binary, compressed, marked up, nonproprietary or proprietary form, including any word processing or hypertext form. However, if you provide access to or distribute copies of a Project Gutenberg™ work in a format other than “Plain Vanilla ASCII” or other format used in the official version posted on the official Project Gutenberg™ website (www.gutenberg.org), you must, at no additional cost, fee or expense to the user, provide a copy, a means of exporting a copy, or a means of obtaining a copy upon request, of the work in its original “Plain Vanilla ASCII” or other form. Any alternate format must include the full Project Gutenberg™ License as specified in paragraph 1.E.1. 1.E.7. Do not charge a fee for access to, viewing, displaying, performing, copying or distributing any Project Gutenberg™ works unless you comply with paragraph 1.E.8 or 1.E.9. 1.E.8. You may charge a reasonable fee for copies of or providing access to or distributing Project Gutenberg™ electronic works provided that: • You pay a royalty fee of 20% of the gross profits you derive from the use of Project Gutenberg™ works calculated using the method you already use to calculate your applicable taxes. The fee is owed to the owner of the Project Gutenberg™ trademark, but he has agreed to donate royalties under this paragraph to the Project Gutenberg Literary Archive Foundation. Royalty payments must be paid within 60 days following each date on which you prepare (or are legally required to prepare) your periodic tax returns. Royalty payments should be clearly marked as such and sent to the Project Gutenberg Literary Archive Foundation at the address specified in Section 4, “Information
  • 58. about donations to the Project Gutenberg Literary Archive Foundation.” • You provide a full refund of any money paid by a user who notifies you in writing (or by e-mail) within 30 days of receipt that s/he does not agree to the terms of the full Project Gutenberg™ License. You must require such a user to return or destroy all copies of the works possessed in a physical medium and discontinue all use of and all access to other copies of Project Gutenberg™ works. • You provide, in accordance with paragraph 1.F.3, a full refund of any money paid for a work or a replacement copy, if a defect in the electronic work is discovered and reported to you within 90 days of receipt of the work. • You comply with all other terms of this agreement for free distribution of Project Gutenberg™ works. 1.E.9. If you wish to charge a fee or distribute a Project Gutenberg™ electronic work or group of works on different terms than are set forth in this agreement, you must obtain permission in writing from the Project Gutenberg Literary Archive Foundation, the manager of the Project Gutenberg™ trademark. Contact the Foundation as set forth in Section 3 below. 1.F. 1.F.1. Project Gutenberg volunteers and employees expend considerable effort to identify, do copyright research on, transcribe and proofread works not protected by U.S. copyright law in creating the Project Gutenberg™ collection. Despite these efforts, Project Gutenberg™ electronic works, and the medium on which they may be stored, may contain “Defects,” such as, but not limited to, incomplete, inaccurate or corrupt data, transcription errors, a copyright or other intellectual property infringement, a defective or
  • 59. damaged disk or other medium, a computer virus, or computer codes that damage or cannot be read by your equipment. 1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except for the “Right of Replacement or Refund” described in paragraph 1.F.3, the Project Gutenberg Literary Archive Foundation, the owner of the Project Gutenberg™ trademark, and any other party distributing a Project Gutenberg™ electronic work under this agreement, disclaim all liability to you for damages, costs and expenses, including legal fees. YOU AGREE THAT YOU HAVE NO REMEDIES FOR NEGLIGENCE, STRICT LIABILITY, BREACH OF WARRANTY OR BREACH OF CONTRACT EXCEPT THOSE PROVIDED IN PARAGRAPH 1.F.3. YOU AGREE THAT THE FOUNDATION, THE TRADEMARK OWNER, AND ANY DISTRIBUTOR UNDER THIS AGREEMENT WILL NOT BE LIABLE TO YOU FOR ACTUAL, DIRECT, INDIRECT, CONSEQUENTIAL, PUNITIVE OR INCIDENTAL DAMAGES EVEN IF YOU GIVE NOTICE OF THE POSSIBILITY OF SUCH DAMAGE. 1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you discover a defect in this electronic work within 90 days of receiving it, you can receive a refund of the money (if any) you paid for it by sending a written explanation to the person you received the work from. If you received the work on a physical medium, you must return the medium with your written explanation. The person or entity that provided you with the defective work may elect to provide a replacement copy in lieu of a refund. If you received the work electronically, the person or entity providing it to you may choose to give you a second opportunity to receive the work electronically in lieu of a refund. If the second copy is also defective, you may demand a refund in writing without further opportunities to fix the problem. 1.F.4. Except for the limited right of replacement or refund set forth in paragraph 1.F.3, this work is provided to you ‘AS-IS’, WITH NO OTHER WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED,
  • 60. INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PURPOSE. 1.F.5. Some states do not allow disclaimers of certain implied warranties or the exclusion or limitation of certain types of damages. If any disclaimer or limitation set forth in this agreement violates the law of the state applicable to this agreement, the agreement shall be interpreted to make the maximum disclaimer or limitation permitted by the applicable state law. The invalidity or unenforceability of any provision of this agreement shall not void the remaining provisions. 1.F.6. INDEMNITY - You agree to indemnify and hold the Foundation, the trademark owner, any agent or employee of the Foundation, anyone providing copies of Project Gutenberg™ electronic works in accordance with this agreement, and any volunteers associated with the production, promotion and distribution of Project Gutenberg™ electronic works, harmless from all liability, costs and expenses, including legal fees, that arise directly or indirectly from any of the following which you do or cause to occur: (a) distribution of this or any Project Gutenberg™ work, (b) alteration, modification, or additions or deletions to any Project Gutenberg™ work, and (c) any Defect you cause. Section 2. Information about the Mission of Project Gutenberg™ Project Gutenberg™ is synonymous with the free distribution of electronic works in formats readable by the widest variety of computers including obsolete, old, middle-aged and new computers. It exists because of the efforts of hundreds of volunteers and donations from people in all walks of life. Volunteers and financial support to provide volunteers with the assistance they need are critical to reaching Project Gutenberg™’s goals and ensuring that the Project Gutenberg™ collection will
  • 61. remain freely available for generations to come. In 2001, the Project Gutenberg Literary Archive Foundation was created to provide a secure and permanent future for Project Gutenberg™ and future generations. To learn more about the Project Gutenberg Literary Archive Foundation and how your efforts and donations can help, see Sections 3 and 4 and the Foundation information page at www.gutenberg.org. Section 3. Information about the Project Gutenberg Literary Archive Foundation The Project Gutenberg Literary Archive Foundation is a non-profit 501(c)(3) educational corporation organized under the laws of the state of Mississippi and granted tax exempt status by the Internal Revenue Service. The Foundation’s EIN or federal tax identification number is 64-6221541. Contributions to the Project Gutenberg Literary Archive Foundation are tax deductible to the full extent permitted by U.S. federal laws and your state’s laws. The Foundation’s business office is located at 809 North 1500 West, Salt Lake City, UT 84116, (801) 596-1887. Email contact links and up to date contact information can be found at the Foundation’s website and official page at www.gutenberg.org/contact Section 4. Information about Donations to the Project Gutenberg Literary Archive Foundation Project Gutenberg™ depends upon and cannot survive without widespread public support and donations to carry out its mission of increasing the number of public domain and licensed works that can be freely distributed in machine-readable form accessible by the widest array of equipment including outdated equipment. Many
  • 62. small donations ($1 to $5,000) are particularly important to maintaining tax exempt status with the IRS. The Foundation is committed to complying with the laws regulating charities and charitable donations in all 50 states of the United States. Compliance requirements are not uniform and it takes a considerable effort, much paperwork and many fees to meet and keep up with these requirements. We do not solicit donations in locations where we have not received written confirmation of compliance. To SEND DONATIONS or determine the status of compliance for any particular state visit www.gutenberg.org/donate. While we cannot and do not solicit contributions from states where we have not met the solicitation requirements, we know of no prohibition against accepting unsolicited donations from donors in such states who approach us with offers to donate. International donations are gratefully accepted, but we cannot make any statements concerning tax treatment of donations received from outside the United States. U.S. laws alone swamp our small staff. Please check the Project Gutenberg web pages for current donation methods and addresses. Donations are accepted in a number of other ways including checks, online payments and credit card donations. To donate, please visit: www.gutenberg.org/donate. Section 5. General Information About Project Gutenberg™ electronic works Professor Michael S. Hart was the originator of the Project Gutenberg™ concept of a library of electronic works that could be freely shared with anyone. For forty years, he produced and distributed Project Gutenberg™ eBooks with only a loose network of volunteer support.
  • 63. Project Gutenberg™ eBooks are often created from several printed editions, all of which are confirmed as not protected by copyright in the U.S. unless a copyright notice is included. Thus, we do not necessarily keep eBooks in compliance with any particular paper edition. Most people start at our website which has the main PG search facility: www.gutenberg.org. This website includes information about Project Gutenberg™, including how to make donations to the Project Gutenberg Literary Archive Foundation, how to help produce our new eBooks, and how to subscribe to our email newsletter to hear about new eBooks.
  • 64. Welcome to our website – the perfect destination for book lovers and knowledge seekers. We believe that every book holds a new world, offering opportunities for learning, discovery, and personal growth. That’s why we are dedicated to bringing you a diverse collection of books, ranging from classic literature and specialized publications to self-development guides and children's books. More than just a book-buying platform, we strive to be a bridge connecting you with timeless cultural and intellectual values. With an elegant, user-friendly interface and a smart search system, you can quickly find the books that best suit your interests. Additionally, our special promotions and home delivery services help you save time and fully enjoy the joy of reading. Join us on a journey of knowledge exploration, passion nurturing, and personal growth every day! ebookbell.com