Some controls such as the DataGrid control provide their own forms of navigation. If you bind a DataGrid to a DataSet, it allows the user to examine the DataSet object’s tables, view and edit data, and follow links between the tables. A simpler control such as a TextBox control can display only one data value at a time. You must provide some means for the program to navigate through the data source’s records.
A data source manages its position within its data by using a CurrencyManager object. The CurrencyManager supervises the list of Binding objects that bind the data source to controls such as TextBoxes.
The following table describes the CurrencyManager object’s most useful properties.
Property | Purpose |
---|---|
Bindings | A collection of the bindings that the object manages. |
Count | Returns the number of rows associated with the CurrencyManager. |
Current | Returns a reference to the current data object (row). |
List | Returns an object that implements the IList interface that provides the data for the CurrencyManager. For example, if the data source is a DataSet or DataTable, this object is a DataView. |
Position | Gets or sets the current position within the data. For example, in a DataTable this is the row number. |
The CurrencyManager also provides some methods for manipulating the data. The following table describes the CurrencyManager object’s most useful methods.
Method | Purpose |
---|---|
AddNew | Adds a new item to the data source. |
CancelCurrentEdit | Cancels the current editing operation. |
EndCurrentEdit | Ends the current editing operation, accepting any changes. |
Refresh | Refills the bound controls. |
RemoveAt | Removes the data source item at a specified index. |
The CurrencyManager class raises a PositionChanged event when its position in the data changes.
The following code shows how a program can use a CurrencyManager to let the user navigate through a DataTable. The code begins by declaring the DataTable and CurrencyManager objects. The form’s Load event handler builds the DataTable and gives it some data. Next the event handler uses the DataBindings collections of several TextBox controls to bind them to the fields in the DataTable. The event handler finishes by saving a reference to the DataTable object’s CurrencyManager. The form’s BindingContext property is a collection that contains references to the BindingManagerBase objects used by the controls on the form. That includes the CurrencyManager used by the DataTable. This code passes the DataTable as a parameter to the BindingContext collection to get the table’s CurrencyManager. If the data source contained multiple objects (for example, a DataSet can contain multiple DataTables), you also need to pass the collection a path to the data object that you want to use.
The user can move through the DataTable by clicking the program’s navigation buttons btnFirst, btnPrev, btnNext, and btnLast. The event handlers for these buttons move through the data by adjusting the CurrencyManager’s Position property.
When the user clicks the Add button, the btnAdd_Click event handler calls the CurrencyManager class’ AddNew method to create a new record.
When the user clicks the Delete button, the btnDelete_Click event handler displays a message box asking if the user really wants to delete the record. When the user clicks Yes, the code uses the CurrencyManager class’s RemoveAt method to delete the current record.
Finally, the CurrencyManager class’s PositionChanged event handler displays the current record’s number and the total number of records. The code adds one to the CurrencyManager class’s Position value because that value starts at zero, but counting from one is more natural to users.
' The data source. Private m_ContactsTable As DataTable ' The data source's CurrencyManager. Private WithEvents m_CurrencyManager As CurrencyManager Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load ' Make a DataTable. m_ContactsTable = New DataTable("Contacts") ' Add columns. m_ContactsTable.Columns.Add("FirstName", GetType(String)) m_ContactsTable.Columns.Add("LastName", GetType(String)) m_ContactsTable.Columns.Add("Street", GetType(String)) m_ContactsTable.Columns.Add("City", GetType(String)) m_ContactsTable.Columns.Add("State", GetType(String)) m_ContactsTable.Columns.Add("Zip", GetType(String)) ' Make the combined FirstName/LastName unique. Dim first_last_columns() As DataColumn = { _ m_ContactsTable.Columns("FirstName"), _ m_ContactsTable.Columns("LastName") _ } m_ContactsTable.Constraints.Add( _ New UniqueConstraint(first_last_columns)) ' Make some contact data. m_ContactsTable.Rows.Add(New Object() {"Art", "Ant", _ "1234 Ash Pl", "Bugville", "CO", "11111"}) m_ContactsTable.Rows.Add(New Object() {"Bev", "Bug", _ "22 Beach St", "Bugville", "CO", "22222"}) m_ContactsTable.Rows.Add(New Object() {"Cid", "Cat", _ "3 Road Place Lane", "Programmeria", "KS", "33333"}) m_ContactsTable.Rows.Add(New Object() {"Deb", "Dove", _ "414 Debugger Way", "Programmeria", "KS", "44444"}) m_ContactsTable.Rows.Add(New Object() {"Ed", "Eager", _ "5746 Elm Blvd", "Bugville", "CO", "55555"}) m_ContactsTable.Rows.Add(New Object() {"Fran", "Fix", _ "647 Foxglove Ct", "Bugville", "CO", "66666"}) m_ContactsTable.Rows.Add(New Object() {"Gus", "Gantry", _ "71762-B Gooseberry Ave", "Programmeria", "KS", "77777"}) m_ContactsTable.Rows.Add(New Object() {"Hil", "Harris", _ "828 Hurryup St", "Programmeria", "KS", "88888"}) ' Bind to controls. txtFirstName.DataBindings.Add("Text", m_ContactsTable, "FirstName") txtLastName.DataBindings.Add("Text", m_ContactsTable, "LastName") txtStreet.DataBindings.Add("Text", m_ContactsTable, "Street") txtCity.DataBindings.Add("Text", m_ContactsTable, "City") txtState.DataBindings.Add("Text", m_ContactsTable, "State") txtZip.DataBindings.Add("Text", m_ContactsTable, "Zip") ' Save a reference to the CurrencyManager. m_CurrencyManager = _ DirectCast(Me.BindingContext(m_ContactsTable), CurrencyManager) End Sub Private Sub btnFirst_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnFirst.Click m_CurrencyManager.Position = 0 End Sub Private Sub btnPrev_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnPrev.Click m_CurrencyManager.Position -= 1 End Sub Private Sub btnNext_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnNext.Click m_CurrencyManager.Position += 1 End Sub Private Sub btnLast_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnLast.Click m_CurrencyManager.Position = m_CurrencyManager.Count - 1 End Sub ' Add a new record. Private Sub btnAdd_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnAdd.Click m_CurrencyManager.AddNew() End Sub ' Delete the current record. Private Sub btnDelete_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnDelete.Click If MsgBox("Are you sure you want to delete this record?", _ MsgBoxStyle.Question Or MsgBoxStyle.YesNo, _ "Confirm Delete?") = MsgBoxResult.Yes _ Then m_CurrencyManager.RemoveAt(m_CurrencyManager.Position) End If End Sub ' Display the CurrencyManager's current Private Sub m_CurrencyManager_PositionChanged(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles m_CurrencyManager.PositionChanged lblPosition.Text = _ "Record " & _ m_CurrencyManager.Position + 1 & _ " of " & _ m_CurrencyManager.Count End Sub
Figure 11-30 shows the program in action.
Figure 11-30: This program’s buttons use a CurrencyManager to let the user add, delete, and navigate through a table’s records.