Virtual Developer Workshop: Containerized Development with Docker

.NET neophytes routinely ask how to bind data to Windows Forms controls. This is a valid beginner question that seasoned .NET users don't ask because they either aren't binding data to controls or they already know how to use DataBindings. No matter which category you fall into, Visual Basic 2005 has evolved and now offers some new features related to data binding.

Visual Studio 2005 and .NET 2.0 support binding to traditional data sources and custom objects. This technology is based on the capabilities of the CodeDOM, typed DataSets, and changes to Forms designers. Collectively, these changes make it possible to define a data source, generate a Windows Form with controls, run the form, and edit the data without writing a single line of code. If the data source is based on a known provider like the SQL provider, the code to populate the data set and write changes is generated automatically. If you use a custom data source, you will have to write a little code to populate the custom objects and a little more code to write changes back to the data source.

This article walks you through the data source's capabilities and demonstrates how the binding source and binding navigator controls are used to provide navigation and binding to WinForms controls. The end of the article demonstrates how you can use reflection to generate controls on the fly and use data bindings programmatically to bind data objects to controls.

Prerequisites for the Article

This article uses Visual Studio .NET 2005 beta 2—its launch is about three weeks away, SQL Server Express 2005, and a copy of the physical SQL Server Northwind database file northwnd.mdf. (SQL Server Express supports a direct connection to physical SQL Server files.)

Tip: Spend a few extra bucks on a beefy computer and install Virtual PC. Virtual PC is an invaluable tool for installing and testing beta software and is an inexpensive way to turn one PC into two or more.

Generating a Form Using a Data Source

Generally, Developer.com doesn't publish articles about wizards because readers are capable enough to walk through the wizards and the wizards are easy enough to follow correctly. However, .NET 2.0 is still new, so you may not know about its wizard-based features, which this article discusses. And, it wraps up with some cool data binding and reflection code that isn't wizard-based.

To create a data source from a SQL Server physical file and generate a data-bound form that is a complete and functional application, take the following steps:

  1. Open Visual Studio 2005.
  2. Create a new Windows Forms project.
  3. Select Data|Add New Data Source.
  4. In the first step of the wizard (entitled Choose a data source type, see Figure 1), select Database.
  5. Figure 1: Select Database to Create a Data Source from an Existing Database

  6. Click Next.
  7. In step 2—choose your data connection—click on New Connection (see Figure 2).
  8. Figure 2: Click New Connection to Create a Connection to the Data Source

  9. In the Change Data Source dialog, select the Microsoft SQL Server Database File (see Figure 3).
  10. Figure 3: Select the Microsoft SQL Server Database File to Connect Directly to a SQL Server Database Store

  11. Click OK.
  12. Browse to your copy of the SQL Server instance of the Northwind database file. (The file will have an .MDF extension, and you can use Windows Explorer to help you find the file. See Figure 4.)
  13. Figure 4: Browse to the Physical Data File, Something Like Northwnd.mdf

  14. To wrap up, choose the database objects (see Figure 5). For the example, select all of the database objects.
  15. Figure 5: Choose All of the Database Objects for the Example

  16. Click Finish to generate the data source.

What Happened?

The designer did a lot of work when you clicked Finish; it created a very large custom-typed DataSet. (This DataSet contains about 23,000 lines of code, because you selected the entire Northwind database.) This DataSet has code that makes it very easy to initialize, bind, modify, and store changes. Additionally, the designer added a data source to the Data Sources explorer (see Figure 6). From this data source, you can easily create as many bound forms you want without a stitch of code.

Figure 6: The Northwind Data Source Is a Visual Representation of the Typed DataSet

Creating the Data Bound Form

By default, the Data Sources explorer elements are set to generate a DataGridView. Simply click on the Customers table (see Figure 6), drag it to a Windows Form, and you have a running application. To generate a detailed view with individual controls (see Figure 7), take the following steps:

  1. Make sure you've selected a Form and the Form is in Designer mode, not code mode. (Make sure you see the Form, not the Form's code.)
  2. Click the drop-down list for the Customers table and select Details.
  3. Drag and drop the Customers table from the Data Sources explorer to a Form.
  4. Press F5.

Step 3 added controls to the form, generated code to populate the Customers data table in the Form_Load event, and bound the controls to a binding source and binding navigator. These controls work together to manage the DataSet and track changes.

Figure 7: The Form Generated by the Data Sources Explorer and Customers Table Set

What Happened?

When you selected Details from the Customers table, you told the designer that you want to generate a details-oriented form with a pair of controls for each column. When you dragged and dropped the Customers table to the form, the designer added the Labels and TextBoxes, a DataSet component, a TableAdapter, a BindingSource, and a BindingNavigator. The BindingNavigator (shown at the top of Figure 7) is used to navigate through the DataSet and it provides controls for managing rows and saving changes. The BindingNavigator talks to the BindingSource, and the BindingSource is data-aware because it has a reference to the DataSet. The TableAdapter is a custom, generated control that is analogous to a DataAdapter but is not derived from the SqlDataAdapter.

All of these components, controls, and code are added or generated for you by the designer. The heavy lifting occurs in the custom DataSet. The Form itself has code for binding columns to controls, handling the initialization, and updating the database from the form. This code is shown in Listing 1.

Listing 1: Some Lightweight Code Generated by the Designer

Public Class Form1
   Private Sub bindingNavigatorSaveItem_Click(ByVal sender As _
      System.Object, _
      ByVal e As System.EventArgs) Handles _

      If Me.Validate Then
         System.Windows.Forms.MessageBox.Show(Me, "Validation _
                                              errors occurred.", _
           "Save", System.Windows.Forms.MessageBoxButtons.OK, _
      End If
   End Sub

   Private Sub Form1_Load(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles MyBase.Load

      ' TODO: This line of code loads data into the
      ' NorthwndDataSet.Customers table. You can move,
      ' or remove it, as needed.
   End Sub
End Class

If you want to view the binding statements, open the *.designer.vb file. For example, if the Form is named Form1.vb, Form1.Designer.vb will contain the code managed by the Forms designer. (Splitting a class into multiple parts is supported by the Partial Classes technology, also new in .NET 2.0.) The code in the last section demonstrates binding objects.

Finally, if you want to manage the dataset using menus or the equivalent of a custom navigator, you can implement event handlers on the binding source component and remove the binding navigator altogether.

Binding to Controls Programmatically

The previous section demonstrated how to create a data-bound form at design time. You can use the same features the IDE uses to create a custom designer or generate forms dynamically at runtime using reflection and data-binding statements. The Form in Figure 8 was generated from the code in Listing 2. The data bindings statements are shown in bold font in the listing.

Figure 8: A Dynamically Generated Data Bound Form

Listing 2: Code for Dynamically Generating a Data-Bound Form

Imports System.Configuration
Imports System.Data
Imports System.Data.SqlClient
Imports System.Reflection

Public Class Form2

   Private Sub Form2_Load(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles MyBase.Load

      Dim table As DataTable = Nothing

      Dim connectionString As String = _
      Using connection As SqlConnection = _
         New SqlConnection(connectionString)

         Dim command As SqlCommand = _
            New SqlCommand("SELECT * FROM CUSTOMERS", connection)
         Dim adapter As SqlDataAdapter = New SqlDataAdapter(command)
         table = New DataTable()
      End Using


   End Sub

   Private Sub GenerateForm(ByVal table As DataTable)
      Dim label As Label
      Dim textBox As TextBox

      Dim I As Integer
      For I = 0 To table.Columns.Count - 1
         label = New Label()
         label.Location = New Point(10, I * 22 + 10)
         label.AutoSize = True
         label.Text = table.Columns(I).ColumnName + ":"

         textBox = New TextBox
         textBox.Location = New Point(100, I * 22 + 10)
         textBox.Width = 200
         textBox.DataBindings.Add("Text", _
            table, table.Columns(I).ColumnName)
  End Sub
End Class

All you need to do to bind a control to a property in something like a DataTable is specify the controls property (Text), the origin of the data (table), and the property in the data source that defines the property that contains the source of data (the column name).

All that remains to complete the sample generated form is to add some navigation controls, and the dynamic form works as well as one that might have taken hours or days to create by hand.

.NET Capabilities for You and Me

A good framework is one that provides the same features to the consumers (we programmers) as it does to the producers (Microsoft programmers). In VB6, all kinds of features existed in the IDE that were very hard—if not impossible—for the consumer to reproduce. However, the Visual Studio IDE uses the same capabilities in the .NET Framework that are available to you and me. This means if the Microsoft programmers can do it, we can too, and groups (Microsoft developers and you and I) are using the same technologies.

The gap is only increasing in power and flexibility between VB6 and VB.NET. Data-binding capabilities, reflection, and generics are just a few productivity capabilities that represent the tip, not the iceberg.

About the Author

Paul Kimmel is the "VB Today" columnist for www.codeguru.com and has written several books on object-oriented programming and .NET. Look for his upcoming books UML DeMystified from McGraw-Hill/Osborne (October 31st, 2005) and C# Express from Addison Wesley (Spring 2006). Paul is an architect for Tri-State Hospital Supply Corporation. You may contact him for technology questions at pkimmel@softconcepts.com.

If you are interested in joining or sponsoring a .NET Users Group, check out www.glugnet.org.

Copyright © 2005 by Paul T. Kimmel. All Rights Reserved.


  • binding navigator

    Posted by liju.thn on 10/16/2007 08:38am

    sir, i hav a binding navigator which is binded to a dataset which is fetching data from customer and insurance tables.while navigating i am displaying the data in some controls in the page.it is working fine.but i hav a datagrid in the form which i want to bind with another table glasses containg customerid as foreign key.so when u navigate thru the records i want the data in the datagrid to change according to the customerid coming on 1 label in the form.how can i do this?also i want to display the last accessed record to display first after i close and open the application.can u help me on this issue

  • Data binding, and GUIDs in VB.Net 2005

    Posted by dna2 on 04/21/2006 12:53pm

    Every time Ibve started using the built in data designers Ibve got frustrated and given up and gone straight in to code it. At Tech Ed they told us for VS 2005 it would be different, these designers are more than just demoware.  Anyway I wanted to see how far I can get with out writing any code.
    This is really simple, create a data entry form for a single table. But it all fails apart because I choose a guid as the ID for the table:
       1. New WinForms VB.Net project.
       2. Add a new data source
       3. Create a table bNotesb
             1. Add column bIDb as uniqueidentifier, rowid, not null and set as the primary key
             2. Other columns too; Body, DateCreated etc..
       4. I use the DataSource Configuration Wizard and my new table is shown.
       5. Then I drag Details from the Table in the Data Sources treeview onto the form and a nice lot of controls and toolbar appear.
       6. Executeb&
    Now when the BindingNavigator tries to add a new record it, the DataSet rejects it. Column ID does not allow nulls. Even if I edit the generated DataSet schema, change it to read only , AllowDBNulls etc.. it has no effect.  If I remove the column entirely then the DataAdapter update fails because it needs to know what row to update. The DataColumn.DefaultValue in the schema isnbt smart enough for SQL Server statements like newid() either.
    So is there a simple way to make my little test app work GUID as the primary key?  (without generating the guid in code)

  • You must have javascript enabled in order to post comments.

Leave a Comment
  • Your email address will not be published. All fields are required.

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date