ConvertTableCellValueToObjectForBinding
================================

This application illustrates two techniques:

1. Binding a property that is a complex type to a single column in a database table; and
2. Using an arraylist of items whose type is a user-defined class as the datasource for a combobox, while binding the SelectedValue property of the comboBox to a column in a database table.

On the main form, a TextBox control, txtBound, has its Font, ForeColor, BackColor, and BorderStyle properties bound to columns in a database table.  However, the Font, ForeColor, and BackColor are all declared in the TextBox class as complex types:  Font takes a System.Drawing.Font object, and the color properties take a System.Drawing.Color object.  In addition, the BorderStyle property take a BorderStyle enumeration type that must be conjured from whatever simple type is stored in the database.

A database table, Property Set, from the PropsIWD database, is used as the source for data binding.  Its structure is as follows:
              ID [int, AutoIncrement]
              FontFamily [string]
              FontSize [double]
              FontBold [boolean]
              FontItalic [boolean]
              FontStrikeout [boolean]
              FontUnderlined [boolean]
              TextToDisplay [string]
              ForeColor [string]
              BackColor [string]
              BorderStyle [unsignedByte]
              Group1X [short]
              Group1Y [short]
              Group2X [short]
              Group2Y [short]
              Group3X [short]
              Group3Y [short]
              Group4X [short]
              Group4Y [short]

Values from the six columns whose names begin with "Font" will become the values of properties of a System.Drawing.Font object that is assigned to the multiply-bound TextBox control txtBound.  ForeColor, BackColor, and BorderStyle will also be converted to appropriate types and assigned to corresponding properties of txtBound.

The four pairs of shorts, GroupnX and GroupnY, are location coordinates for GroupBoxes that appear on the form. They are used in a second phase of the demonstration.

Suggested Exercise
------------------------
Launch the app and use the navigational buttons to move among the five records.  Note the changes in the appearance of the txtBound TextBox.  All changes are data-driven through binding.  Not simply the text that displays in the TextBox, but the font in which it is displayed, and the ForeColor, BackColor, and BorderStyle are changed, driven by data in the backend database.

For convenience, I have also placed controls on the form that display (through binding) the current values for the various columns of the database that provide the data on which changes in the TextBox's appearance are based. However, these TextBoxes are incidental to the binding of the txtBound properties and play no role in the functioning of that.

Now check the "Bind Group Locations" checkbox.  Checking this boxes causes bindings to be set on the Location property of the form's four GroupBox controls.  The locations of those get bound to the pairs of GroupnX and GroupnY columns in the PropertySet table.  If you are on the first record in the set when you make this change, you will see no effects until you navigate to a different record - because the location coordinates in the database for the first record are the same as the locations hard-coded in the form.  Navigate through the records and note how the controls on the form now get rearranged, along with the previous transformations in the appearance of the txtBound control.   At some point, uncheck the "Bind Group Locations" checkbox, navigate among the records, and note that once the bindings are removed the form retains whatever layout you left it with for the remainder of the session.

Clearly there are many possibilities for these techniques.  You could, for example, provide users with rich customization facilities in your app, all data-driven and instantly morphable.  Or you could color-code or otherwise highlight and emphasize various data values on a record-by-record basis to suit whatever your purpose might be.

Key Techniques Illustrated
------------------------------
The most important technique illustrated in this app is the use of the Format event of the Binding class to transform simple types stored in a database into the complex types required by many of the .NET controls. When, for example, the Font property of txtBound is bound to the value in a DataTable column, I have to do a little trick (since a DataTable column doesn't know how to store a font object). What I do is to bind the property to the ID column of the DataTable -- its primary key -- and then add a handler for the binding's Format event, which fires as data comes into the bound control.  The event handler for the Format event transforms the simple type data coming from the DataTable into the complex Font type, delivering that to the control.

        Dim bindingFont As New Binding("Font", m_tblPropSet, "ID")
        AddHandler bindingFont.Format, AddressOf ConvertDataToFont
        Me.txtBound.DataBindings.Add(bindingFont)

Here's the event handler.  It constructs a Font object with attributes determined by the incoming data values, then assigns that to the Value property of the ConvertEventArgs parameter of the method:

    Private Sub ConvertDataToFont(ByVal sender As Object, ByVal e As ConvertEventArgs)
        Dim intCurrentRow As Int32 = Me.BindingContext(Me.objdsPropSet.PropertySet).Position
        Dim rowCurr As DataRow = Me.objdsPropSet.PropertySet.Rows(intCurrentRow)

        Dim fontstyleX As New System.Drawing.FontStyle
        If rowCurr("FontBold") Then fontstyleX = FontStyle.Bold
        If rowCurr("FontItalic") Then fontstyleX += FontStyle.Italic
        If rowCurr("FontStrikeout") Then fontstyleX += FontStyle.Strikeout
        If rowCurr("FontUnderlined") Then fontstyleX += FontStyle.Underline
        Dim strFontFamily As String = rowCurr("FontFamily")
        Dim sglFontSize As Single = rowCurr("FontSize")
        e.Value = New Font(strFontFamily, sglFontSize, fontstyleX)
    End Sub
    
Other properties of txtBound are supplied in similar ways.  You can examine the code for the details.

