Databinding in Windows Forms

Before reading this Quick Start you should read the ADO.NET Overview.

The last three samples use XML Web services. Read the XML Web services Overview before reviewing those samples.

Introduction

Data binding provides a simple, convenient, powerful, and transparent way for developers to create a read/write link between the controls on a form and the data in their application (their data model).

Windows Forms supports binding data to ADO.NET DataSet controls, Array controls, ArrayList controls, and so on. A control can be bound to any collection that supports indexed access to the elements in that collection -- to be specific, to any collection that implements the IList interface.

Simple Data Binding

Simple data binding means binding a single value within the data model to a single property of a control. For example, binding TextBox1.Text to Customer.Name. Simple binding is managed by use of the Bindings collection on each control.

Complex Data Binding

Complex data binding means binding a control to a collection (rather than binding a control to a single item within the collection). For example, the DataGrid has a DataSource property that can be set to an entire DataSet or Array. The DataGrid extracts information from the DataSource and displays it. ListBox and ComboBox also use complex data binding.

One-Way and Two-Way Data Binding

One-way data binding describes a process by which a property of a control is bound to the data model for read-only or presentation purposes. When data binding is set up in this fashion, the property reflects the value of the data, but direct changes to the property are not reflected in the data model.

Two-way data binding describes a process by which a property of a control is bound to the data model in a read/write manner. When data binding is set up in this fashion, the property reflects the value of the data and changes to the property are propogated to the data model.

The BindingContext

Each Form has a BindingContext. The BindingContext is responsible for managing the collections of data that controls are bound to. It manages currency and dependency.

Currency: The BindingContext maintains a current position for each collection. Simple data binding uses this current position to determine which object in the collection to bind to a control property. As the current position is changed, so does the object that a control property is bound to. See Simple Data Binding.

Dependency: The BindingContext maintains dependency relationships between collections. This allows for the creation of master/detail forms. See Master Detail Forms.

Simple Data Binding

This sample demonstrates simple data binding of the Text property on a set of TextBox controls to the properties of a Customer object that is stored as a list of customers. You add simple data bindings by using the DataBindings collection on a control.


textBoxID.DataBindings.Add("Text", custList, "CustomerID")
textBoxTitle.DataBindings.Add("Text", custList, "ContactTitle")
textBoxLastName.DataBindings.Add("Text", custList, "ContactName")
textBoxFirstName.DataBindings.Add("Text", custList, "CompanyName")
textBoxAddress.DataBindings.Add("Text", custList, "Address")
VB

Each TextBox.Text is bound to the current Customer object, as maintained by the BindingContext. To change the current object, you increment or decrement the Position property for the collection by use of the BindingContext. For example, you implement a Move Next button by handling the button's Click event as follows.


Private Sub buttonMoveNext_Click(sender As Object, e As System.EventArgs)
    Me.BindingContext(custList).Position += 1
End Sub
VB

The BindingContext raises an event whenever the position changes.


AddHandler Me.BindingContext(custList).PositionChanged, AddressOf customer_PositionChanged

Private Sub customer_PositionChanged(sender As Object, e As System.EventArgs)
    textBoxPosition.Text = "Record " & (Me.BindingContext(custList).Position + 1) _
                                     & " of " & custList.Length
End Sub
VB

To view and run this sample.

 
VB Simple Data binding

[Run Sample] | [View Source]

Binding to a ComboBox or ListBox

This sample demonstrates binding data to a ComboBox. Binding data to a ListBox follows the same model.

To bind data to the list of items that are displayed, set the DataSource and DisplayMember properties of the ComboBox. The DisplayMember property is used to determine which property of the State object to display in the ComboBox. For example, the following code binds a ComboBox to an array of State objects.


Public Structure State
    Private m_shortName, m_longName As String

    Public Sub New(ByVal longName As String, ByVal shortName As String)
        Me.m_shortName = shortName
        Me.m_longName = longName
    End Sub

    Public ReadOnly Property ShortName() As String
        Get
            Return m_shortName
        End Get
    End Property

    Public ReadOnly Property LongName() As String
        Get
            Return m_longName
        End Get
    End Property
End Structure

Private States() As State = {New State("Alabama", "AL"), ..., New State("Wyoming", "WY")}

comboBoxState.DataSource=States
comboBoxState.DisplayMember="LongName"
VB

Typically, in a data-bound form, a ComboBox is used to look up up a value. In this example, the form displays a Customer object. Each Customer object has a Region property that contains a state's abbreviated name. You want to display a list of full state names that the user can select from. When the user selects a particular state, you want the Customer region to be updated with the state's abbreviated name, rather than the full name. In order to achieve this, you can do the following:

  • set the ComboBox up like the previous example
  • set the ValueMember property to point to the state abbreviation property on the State object - State.ShortName
  • simple-bind SelectedValue to Customer.Region

The ValueMember property determines which value gets moved into SelectedValue. In the example, whenever the user selects a state by State.LongName, the SelectedValue is the State.ShortName. Whenever the SelectedValue changes, the data-binding moves the new value into the Customer object.


comboBoxState.DataSource=States
comboBoxState.DisplayMember="LongName"
comboBoxState.ValueMember="ShortName"
comboBoxState.DataBindings.Add("SelectedValue", customersDataSet1, "Customers.Region")
VB

To view and run this sample.

 
VB ComboBox binding

[Run Sample] | [View Source]

Binding to a DataGrid

The DataGrid displays all the information in an array, collection, or ADO.NET DataTable, as a series of rows. Each row can be edited in place. Changes are automatically moved back into the underlying collection of objects as the user moves from row to row.

When the DataGrid is used to view a DataSet, the user can move across the DataTable objects in a DataSet through their relationships.

In order to use a DataGrid, you simply set the DataSource property to the list of objects to display. If the DataSource is a DataSet, you also need to set the DataMember property to the DataTable to display.


dataGrid1.Size = New System.Drawing.Size(584, 336)
dataGrid1.DataSource = customersDataSet1
dataGrid1.DataMember = "Customers"
VB

There are a set of properties on the DataGrid that allow you to change the way it displays data. For example, you can set the AlternatingBackColor property to cause alternate rows to be displayed with varying BackColor properties.


dataGrid1.DataSource = customersDataSet1
dataGrid1.DataMember = "Customers"
dataGrid1.ForeColor = System.Drawing.Color.Navy
dataGrid1.BackColor = System.Drawing.Color.Gainsboro
dataGrid1.AlternatingBackColor = System.Drawing.Color.WhiteSmoke
VB

The DataGrid sample demonstrates how to load a DataSet and display its contents in a DataGrid.

 
VB Grid binding

[Run Sample] | [View Source]
Using a XML Web service to Retrieve a DataSet

The .Net Framework based applications expose services as XML Web services. XML Web services can return data. Windows Forms applications can use a XML Web service to retrieve data and bind to that returned data. This sample demonstrates binding to data returned from a Web Service.

Before walking through this sample, you should be familar with XML Web services. See the XML Web services Overview.

The first step is to create a XML Web service that returns a DataSet.


<%@ WebService Language="VB" Class="CustomersList"%>

Imports System.Web.Services
Imports System.Data
Imports System.Data.SqlClient
Imports Microsoft.Samples.WinForms.VB.WebServiceBinding.Data

public class CustomersList
        Inherits WebService

     <WebMethod()> Public Function GetCustomers() As DataSet
         Dim customersDataSet1 As New CustomersDataSet
         Dim con As SqlConnection = new SqlConnection("server=(local)\VSdotNET;Trusted_Connection=yes;database=northwind")
         Dim cmdCustomers As SqlDataAdapter  = new SqlDataAdapter("Select * from Customers", con)
         Dim cmdOrders As SqlDataAdapter = new SqlDataAdapter("Select * from Orders", con)
         cmdCustomers.Fill(customersDataSet1, "Customers")
         cmdOrders.Fill(customersDataSet1, "Orders")
         return customersDataSet1
     End Function

End Class
VB


You can view this XML Web service at CustomersList.

Having created the Web Service, you then need to create a WSDL file that defines the schema for that Web Service. You can get the WSDL by connecting to the XML Web service with the ?WSDL parameter- CustomersList WSDL.

Once you have the WSDL file, you can then create a client proxy source file by using WebServiceUtil.exe.


wsdl.exe /l:VB /n:SimpleWebService /o:SimpleCustomersWebService.vb SimpleCustomersWebService.WSDL
VB

Once you have the proxy source file, you can compile it into your application and use it to retrieve the data from the Web Service.


Dim custList1 As New CustomersList
Dim ds1 As DataSet = custList1.GetCustomers
dataGrid1.DataSource=ds1
VB

The XML Web services sample demonstrates how to load a DataSet from a XML Web service and display its contents in a DataGrid.

 
VB Grid binding to a Web Service

[Run Sample] | [View Source]
Master Detail Forms

In database applications, it is often useful to view a record with a group of related records. For example, you may want to view a customer with the current orders for that customer. A common way to accomplish this is to create a master/detail form.

This sample displays a Datagrid for customers and a DataGrid for the orders for each customer. The first DataGrid displays the list of customers. The second DataGrid displays the list of orders. As the selected customer changes, the second DataGrid updates to display the orders for that customer.

In order to link the two DataGrid objects, you need to set the DataSource of each DataGrid to the same DataSet. You also need to set the DataMember properties to indicate to the Windows Forms BindingContext that they are related. You do this by setting the DataMember for the second DataGrid to the name of the relationship between the Customers and Orders tables - Customers.CustomersOrders.


dataGrid1.DataSource = customersAndOrdersDataSet1
dataGrid1.DataMember = "Customers"

dataGrid2.DataSource = customersAndOrdersDataSet1
dataGrid2.DataMember = "Customers.CustomersOrders"
VB

To view and run this sample.

 
VB MasterDetails

[Run Sample] | [View Source]

Customer Details Form

This sample demonstrates the following:

  • Writing a XML Web service that fills a DataSet and returns it
  • Writing a XML Web service that saves the updates from a DataSet in the database
  • Binding to that DataSet
  • Updating the DataSet and tracking changes in the Form
  • Extracting changed rows from the DataSet and sending them to the Update Web Service
  • Reconciling the saved rows and displaying errors

To view and run this sample.

 
VB Customer Details Form

[Run Sample] | [View Source]


Copyright 2001 Microsoft Corporation. All rights reserved.