Click here to Skip to main content
15,895,084 members
Articles / Programming Languages / Visual Basic

Using Reflection to Bind Object Data to Data Sources

Rate me:
Please Sign up or sign in to vote.
4.54/5 (16 votes)
26 May 20059 min read 69.6K   564   55  
This article describes classes that can be used to update data sources with object data via reflection.
Imports System.Reflection
Imports FES.Data.Bind

#Region " Copyright Notice: "

'Copyright 2005 Front End Software, Joe Cleland
'-----------------------------------------------
'You have permission to use/distribute this software as long as this copyright
'notice is included.
'
'By using this software you agree that you are using it "AS-IS".
'There is No warranty for the maintenance or performance of this software.
'You shall not hold Front End Software, Joe Cleland or any affiliations
'responsible for any loss or damage you may incur by using this software.

#End Region


Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents DataGrid1 As System.Windows.Forms.DataGrid
    Friend WithEvents CtlEmployee1 As ctlEmployee
    Friend WithEvents GroupBox1 As System.Windows.Forms.GroupBox
    Friend WithEvents Label1 As System.Windows.Forms.Label
    Friend WithEvents Label2 As System.Windows.Forms.Label
    Friend WithEvents Label3 As System.Windows.Forms.Label
    Friend WithEvents nudCount As System.Windows.Forms.NumericUpDown
    Friend WithEvents btnTestBinding As System.Windows.Forms.Button
    Friend WithEvents Label4 As System.Windows.Forms.Label
    Friend WithEvents lblTestResult As System.Windows.Forms.Label
    Friend WithEvents Label5 As System.Windows.Forms.Label
    Friend WithEvents rdoUseAttributes As System.Windows.Forms.RadioButton
    Friend WithEvents rdoUseMemberBindings As System.Windows.Forms.RadioButton
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.DataGrid1 = New System.Windows.Forms.DataGrid()
        Me.CtlEmployee1 = New ctlEmployee()
        Me.GroupBox1 = New System.Windows.Forms.GroupBox()
        Me.rdoUseMemberBindings = New System.Windows.Forms.RadioButton()
        Me.rdoUseAttributes = New System.Windows.Forms.RadioButton()
        Me.Label4 = New System.Windows.Forms.Label()
        Me.btnTestBinding = New System.Windows.Forms.Button()
        Me.nudCount = New System.Windows.Forms.NumericUpDown()
        Me.Label3 = New System.Windows.Forms.Label()
        Me.Label2 = New System.Windows.Forms.Label()
        Me.Label1 = New System.Windows.Forms.Label()
        Me.lblTestResult = New System.Windows.Forms.Label()
        Me.Label5 = New System.Windows.Forms.Label()
        CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.GroupBox1.SuspendLayout()
        CType(Me.nudCount, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        'DataGrid1
        '
        Me.DataGrid1.DataMember = ""
        Me.DataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText
        Me.DataGrid1.Location = New System.Drawing.Point(12, 69)
        Me.DataGrid1.Name = "DataGrid1"
        Me.DataGrid1.ReadOnly = True
        Me.DataGrid1.Size = New System.Drawing.Size(321, 186)
        Me.DataGrid1.TabIndex = 1
        '
        'CtlEmployee1
        '
        Me.CtlEmployee1.EmployeeData = Nothing
        Me.CtlEmployee1.Location = New System.Drawing.Point(348, 69)
        Me.CtlEmployee1.Name = "CtlEmployee1"
        Me.CtlEmployee1.Size = New System.Drawing.Size(315, 423)
        Me.CtlEmployee1.TabIndex = 2
        '
        'GroupBox1
        '
        Me.GroupBox1.Controls.AddRange(New System.Windows.Forms.Control() {Me.rdoUseMemberBindings, Me.rdoUseAttributes, Me.Label4, Me.btnTestBinding, Me.nudCount, Me.Label3, Me.Label2, Me.Label1, Me.lblTestResult})
        Me.GroupBox1.Location = New System.Drawing.Point(12, 267)
        Me.GroupBox1.Name = "GroupBox1"
        Me.GroupBox1.Size = New System.Drawing.Size(321, 222)
        Me.GroupBox1.TabIndex = 3
        Me.GroupBox1.TabStop = False
        Me.GroupBox1.Text = "Binding Test"
        '
        'rdoUseMemberBindings
        '
        Me.rdoUseMemberBindings.Location = New System.Drawing.Point(9, 129)
        Me.rdoUseMemberBindings.Name = "rdoUseMemberBindings"
        Me.rdoUseMemberBindings.Size = New System.Drawing.Size(306, 18)
        Me.rdoUseMemberBindings.TabIndex = 8
        Me.rdoUseMemberBindings.Text = "Use a MemberBindingCollection"
        '
        'rdoUseAttributes
        '
        Me.rdoUseAttributes.Checked = True
        Me.rdoUseAttributes.Location = New System.Drawing.Point(9, 108)
        Me.rdoUseAttributes.Name = "rdoUseAttributes"
        Me.rdoUseAttributes.Size = New System.Drawing.Size(306, 18)
        Me.rdoUseAttributes.TabIndex = 7
        Me.rdoUseAttributes.TabStop = True
        Me.rdoUseAttributes.Text = "Use the Employee object (pull from attributes)"
        '
        'Label4
        '
        Me.Label4.AutoSize = True
        Me.Label4.Location = New System.Drawing.Point(24, 186)
        Me.Label4.Name = "Label4"
        Me.Label4.Size = New System.Drawing.Size(45, 13)
        Me.Label4.TabIndex = 5
        Me.Label4.Text = "Results:"
        '
        'btnTestBinding
        '
        Me.btnTestBinding.Location = New System.Drawing.Point(147, 153)
        Me.btnTestBinding.Name = "btnTestBinding"
        Me.btnTestBinding.TabIndex = 4
        Me.btnTestBinding.Text = "Test"
        '
        'nudCount
        '
        Me.nudCount.Location = New System.Drawing.Point(72, 153)
        Me.nudCount.Maximum = New Decimal(New Integer() {1000000, 0, 0, 0})
        Me.nudCount.Minimum = New Decimal(New Integer() {1, 0, 0, 0})
        Me.nudCount.Name = "nudCount"
        Me.nudCount.Size = New System.Drawing.Size(72, 20)
        Me.nudCount.TabIndex = 3
        Me.nudCount.Value = New Decimal(New Integer() {1000, 0, 0, 0})
        '
        'Label3
        '
        Me.Label3.AutoSize = True
        Me.Label3.Location = New System.Drawing.Point(24, 153)
        Me.Label3.Name = "Label3"
        Me.Label3.Size = New System.Drawing.Size(34, 13)
        Me.Label3.TabIndex = 2
        Me.Label3.Text = "Count"
        '
        'Label2
        '
        Me.Label2.Location = New System.Drawing.Point(9, 51)
        Me.Label2.Name = "Label2"
        Me.Label2.Size = New System.Drawing.Size(306, 54)
        Me.Label2.TabIndex = 1
        Me.Label2.Text = "This test will bind the first row of the data table to an instance of the Employe" & _
        "e class. This is repeated for as many time as you determine. The results are rep" & _
        "orted below."
        '
        'Label1
        '
        Me.Label1.Location = New System.Drawing.Point(9, 15)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(306, 33)
        Me.Label1.TabIndex = 0
        Me.Label1.Text = "This test shows the speed of binding data using the DataSourceBinder."
        '
        'lblTestResult
        '
        Me.lblTestResult.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        Me.lblTestResult.Location = New System.Drawing.Point(72, 183)
        Me.lblTestResult.Name = "lblTestResult"
        Me.lblTestResult.Size = New System.Drawing.Size(150, 33)
        Me.lblTestResult.TabIndex = 6
        '
        'Label5
        '
        Me.Label5.Location = New System.Drawing.Point(169, 9)
        Me.Label5.Name = "Label5"
        Me.Label5.Size = New System.Drawing.Size(357, 54)
        Me.Label5.TabIndex = 0
        Me.Label5.Text = "The data table in the grid on the left is bound to the employee data displayed on" & _
        " the right. All changes made to the employee data are reflected in the datagrid." & _
        ""
        Me.Label5.TextAlign = System.Drawing.ContentAlignment.TopCenter
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(694, 519)
        Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.Label5, Me.GroupBox1, Me.CtlEmployee1, Me.DataGrid1})
        Me.MaximizeBox = False
        Me.MinimizeBox = False
        Me.Name = "Form1"
        Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
        Me.Text = "DatasourceBinder Example"
        CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).EndInit()
        Me.GroupBox1.ResumeLayout(False)
        CType(Me.nudCount, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)

    End Sub

#End Region

    Private WithEvents oCurrencymanager As CurrencyManager
    Private WithEvents oEmployee As Employee
    Private oBinder As DataSourceBinder
    Private oTable As DataTable

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

        'Create the Employee instance. This single instance will be used to 
        'edit records of the table.
        oEmployee = New Employee()

        'Create our instance of the data source binder.
        oBinder = New DataSourceBinder()


        'Normally the data would come from a database. For this example 
        'I have included the data as an embedded resource. This data originally came
        'from the Northwind Employees table.
        Dim oDS As New DataSet()
        Dim oStream As IO.Stream = [Assembly].GetExecutingAssembly.GetManifestResourceStream("Employees.xml")
        Dim oReader As New Xml.XmlTextReader(oStream)

        oDS.ReadXml(oReader)

        oTable = oDS.Tables(0)

        'Bind the table to the data grid.
        Me.DataGrid1.DataSource = oTable

        'Set up the currency manager so we can track when the user moves to 
        'a different row.
        oCurrencymanager = DirectCast(Me.BindingContext(oTable), CurrencyManager)

        'Call oCurrencymanager_PositionChanged to get things rolling.
        Call oCurrencymanager_PositionChanged(Me, New EventArgs())

    End Sub

    Private Sub oCurrencymanager_PositionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles oCurrencymanager.PositionChanged


        'Get the currently selected row.
        Dim oRowView As DataRowView = DirectCast(oCurrencymanager.Current, DataRowView)

        '<- Just one line to bind all values! Including the read-only EmployeeID!! ->
        oBinder.SetValues(oEmployee, oRowView.Row)


        'Load the employee control with the employee object.
        'This will force the control to re-bind to the object.
        Me.CtlEmployee1.EmployeeData = oEmployee


    End Sub

    Private Sub oEmployee_PropertyChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles oEmployee.PropertyChanged



        'Get the currently selected row.
        Dim oRowView As DataRowView = DirectCast(oCurrencymanager.Current, DataRowView)


        'Use the binder to copy the changed data into the datarow.
        'This might normally be done after all the object data has been changed.
        '(for example right before an update). I chose to do this after each 
        'property change to show the data in the datagrid change as data in the
        'employee control is modified.

        '<- Again, only one line of code to copy all the data back into the datarow! ->
        oBinder.GetValuesIntoDataRow(oEmployee, oRowView.Row)

    End Sub

    Private Sub btnTestBinding_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTestBinding.Click

        Try
            Cursor = Cursors.WaitCursor

            Dim iCount As Integer = 0
            Dim iMax As Integer = CType(Me.nudCount.Value, Integer)

            Dim oLocalEmployee As New Employee()
            Dim oRow As DataRow = oTable.Rows(0)

            Me.lblTestResult.Text = String.Empty

            Dim dtStart As Date
            Dim dtEnd As Date

            If Me.rdoUseAttributes.Checked Then

                'Run the test using the Employee object directly.
                'The DataDourceBinder internally builds a MemberBindings
                'from the attributes defined in the class.
                dtStart = Date.Now
                Do While iCount < iMax
                    oBinder.SetValues(oLocalEmployee, oRow)
                    iCount += 1
                Loop
                dtEnd = Date.Now

            Else

                'Run the test using a MemberBindingCollection directly.

                'For the test I build the MemberBindingCollection from 
                'the DataField attributes of the Employee class.
                'In theory, I could programatically build the 
                'MemberBindingCollection and bind to an object that does not
                'have any DataField attributes defined.
                Dim oMemberBindings As MemberBindingCollection _
                = DataFieldAttribute.GetMemberBindingsForType(GetType(Employee))

                dtStart = Date.Now
                Do While iCount < iMax
                    oBinder.SetValues(oLocalEmployee, oMemberBindings, oRow)
                    iCount += 1
                Loop
                dtEnd = Date.Now

            End If


            Me.lblTestResult.Text = dtEnd.Subtract(dtStart).ToString

        Catch x As Exception

            MsgBox(x.Message, MsgBoxStyle.Critical, "ERROR!")

        Finally
            Cursor = Cursors.Default

        End Try
    End Sub

End Class

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
I was born in Colorado but have lived most of my life in Southern California. I live a largely ordinary life with occasional extraordinary intervening events.

I am an independent contractor who is blessed to have the opportunity to do work that I love and still earn enough money to pay the bills.

Comments and Discussions