21.3. Object Data Source

In a number of projects, an application is broken up into multiple tiers. Quite often it is not possible to pass around strongly typed DataSets, because they may be quite large, or perhaps the project requires custom business objects. In either case, it is possible to take the DataBinding techniques you just learned for DataSets and apply them to objects. For the purposes of this discussion, use the following Customer and SalesOrder classes:

Public Class Customer
    Private m_Name As String
    Public Property Name() As String
        Get
            Return m_Name
        End Get
        Set(ByVal value As String)
            m_Name = value
        End Set
    End Property

    Private m_Orders As New List(Of SalesOrder)
    Public Property Orders() As List(Of SalesOrder)
        Get
            Return m_Orders
        End Get
        Set(ByVal value As List(Of SalesOrder))
            m_Orders = value
        End Set
    End Property
End Class

Public Class SalesOrder
    Implements System.ComponentModel.IDataErrorInfo

    Private m_Description As String
    Public Property Description() As String
        Get
            Return m_Description
        End Get
        Set(ByVal value As String)
            m_Description = value
        End Set
    End Property

    Private m_Quantity As Integer
    Public Property Quantity() As Integer
        Get
            Return m_Quantity
        End Get
        Set(ByVal value As Integer)
            m_Quantity = value
        End Set
    End Property

    Private m_DateOrdered As Date
    Public Property DateOrdered() As Date
        Get
            Return m_DateOrdered
        End Get
        Set(ByVal value As Date)
            m_DateOrdered = value
        End Set
    End Property

    Public ReadOnly Property ErrorSummary() As String _
                              Implements System.ComponentModel.IDataErrorInfo.Error
        Get
            Dim summary As New System.Text.StringBuilder
            Dim err As String = ErrorItem("Description")
            If Not err = "" Then summary.AppendLine(err)
            err = ErrorItem("Quantity")
            If Not err = "" Then summary.AppendLine(err)
            err = ErrorItem("DateOrdered")
            If Not err = "" Then summary.AppendLine(err)
            Return summary.ToString
        End Get
    End Property

    Default Public ReadOnly Property ErrorItem(ByVal columnName As String) _
                     As String Implements System.ComponentModel.IDataErrorInfo.Item
        Get
            Select Case columnName
                Case "Description"
                    If Me.m_Description = "" Then _

Return "Need to order item description"
                Case "Quantity"
                    If Me.m_Quantity <= 0 Then _
                          Return "Need to supply quantity of order"
                Case "DateOrdered"
                    If Me.m_DateOrdered > Now Then _
                          Return "Need to specify a date in the past"
            End Select
            Return ""
        End Get
    End Property
End Class

To use DataBinding with custom objects, follow roughly the same process as you did with DataSets. Add a new data source via the Data Sources window. This time, select an Object Data Source type. Doing so will display a list of available classes within the solution, as shown in Figure 21-20.

Figure 21.20. Figure 21-20

Select the Customer class and complete the wizard to add the Customer class, along with the nested list of orders, to the Data Sources window, as shown in Figure 21-21.

Figure 21.21. Figure 21-21

As you did previously, you can select the type of control you want for each of the fields before dragging the Customer node onto the form. Doing so adds a CustomerBindingSource and a CustomerNavigator to the form. If you set the Orders list to be a DataGridView and drag that onto the form, you will end up with the layout shown in Figure 21-22. As you did previously with the DataGridView, again opt to modify the default list of columns using the Edit Columns dialog accessible from the smart tag dialog.

Figure 21.22. Figure 21-22

Unlike binding to a DataSet that has a series of TableAdapters to extract data from a database, there is no automatically generated fill mechanism for custom objects. The process of generating the customer objects is usually handled elsewhere in the application. All you have to do here is issue the following code snippet to link the existing list of customers to the CustomerBindingSource so they can be displayed:

Private Sub Form1_Load(ByVal sender As System.Object, _
                        ByVal e As System.EventArgs) Handles MyBase.Load
    Me.CustomerBindingSource.DataSource = GetCustomers()
End Sub

Public Function GetCustomers() As Customer()
    'Populate customers list..... eg from webservice
    Dim cust As Customer() = New Customer() { _
                                      New Customer With {.Name = "Joe Blogs"}, _
                                      New Customer With {.Name = "Sarah Burner"}, _
                                      New Customer With {.Name = "Matt Swift"}, _
                                      New Customer With {.Name = "Barney Jones"}}
    Return cust
End Function

Running this application provides a simple interface for working with customer objects.

21.3.1. IDataErrorInfo

You will notice in the code provided earlier that the SalesOrder object implements the IDataErrorInfo interface. This is an interface that is understood by the DataGridView and can be used to validate custom objects. As you did in the earlier application, you need to add an ErrorProvider to the form. Instead of manually wiring up events in the ErrorProvider control, in conjunction with the DataGridView use the IDataErrorInfo interface to validate the SalesOrder objects. The running application is shown in Figure 21-23, where an invalid date and no quantity have been specified for a SalesOrder.

Figure 21.23. Figure 21-23

The icon at the end of the row provides a summary of all the errors. This is determined by calling the Error property of the IDataError interface. Each of the columns in turn provides an icon to indicate which cells are in error. This is determined by calling the Item property of the IDataError interface.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.198.81