none
Binding a collection of textboxes in a FlowLayoutPanel to a table row(s)

    Question

  • I have a VB.NET Windows Form with FlowLayoutPanel that will contain one or more text boxes.  I would like to bind the collection of textboxes to a row(s) from a table in a SQL 2005 database using a dataset.  As an example, I have a OrdersTable and an OrderItems table in the Parent-Child relationship.  When adding new order items to a new order, I would like to add a new textbox control as the user adds items in the FlowLayoutPanel.  A blank or empty textbox will signal the last items for that order.  In addition, if a users navigates to an existing order, the FlowLayoutPanel would need to add the child rows as textboxes in the same order they were keyed. 

    My first approach was to just try and get user interface behavior (never mind the databinding yet) to work by adding a new textbox and naming it based on the current count of the control collection in the container:

    Private Sub addOrderItem()

    Dim newTextBox As New TextBox

    ' the next line will throw an error at runtime...not sure why.

    newTextBox.Name = "txtOrderItem" & sampleFlowLayoutPanel.Container.Components.Count

    sampleFlowLayoutPanel.Controls.Add(newTextBox)

    End Sub

    I have a command button that calls addOrderItem().  However, the above code throws and error becase the object is Nothing.  I'm not sure why the object would be nothing since it contains at least one textbox when the program is launched. 

    Thanks!

    DeBug

    Monday, March 19, 2007 12:30 AM

All replies

  • Hi,

    try replacing sampleFlowLayoutPanel.Container.Components.Count with sampleFlowLayoutPanel.Controls.Count .

    Andrej

    Monday, March 19, 2007 8:33 AM
  • Yes, that fixed the issue with counting the controls.  However, the larger question of databinding was the focus of my question.  The more I search and read up on complex databinding, the more I belive you can not directly bind a collection control to a dataset.

    I'm open for suggestions on where to look for a solution.  Below is what I have so far.

    DeBug

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

    sampleFlowLayoutPanel.AutoScroll = True

    sampleFlowLayoutPanel.WrapContents = False

    sampleFlowLayoutPanel.FlowDirection = FlowDirection.TopDown

    addOrderItem()

    End Sub

    Private Sub addOrderItem()

    Dim tbOrderItem As New TextBox

    tbOrderItem.Width = 150

    AddHandler tbOrderItem.GotFocus, New eventhandler(AddressOf Me.tb_GotFocus)

    AddHandler tbOrderItem.LostFocus, New eventhandler(AddressOf Me.tb_LostFocus)

    sampleFlowLayoutPanel.Controls.Add(tbOrderItem)

    tbOrderItem.Focus()

    End Sub

    Private Sub tb_GotFocus(ByVal sender As Object, ByVal e As EventArgs)

    Dim o As TextBox

    o = CType(sender, TextBox)

    o.BackColor = System.Drawing.Color.FromArgb _

    (CType(CType(255, Byte), Integer), _

    CType(CType(255, Byte), Integer), _

    CType(CType(192, Byte), Integer))

    End Sub

    Private Sub tb_LostFocus(ByVal sender As Object, ByVal e As EventArgs)

    Dim o As TextBox

    o = CType(sender, TextBox)

    o.BackColor = Color.White

    If o.Text.Length > 0 Then

    addOrderItem()

    Else

    Me.sampleFlowLayoutPanel.Controls.Remove(o)

    End If

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    addOrderItem()

    End Sub

    End Class

    Thursday, March 22, 2007 12:49 AM
  • As I see from your code, you're kind of creating your own data grid? Is there any special reason why you don't use the DataGridView control?

    Andrej

    Thursday, March 22, 2007 9:06 AM
  • I guess that started out as a user requirement.  That is to say that I'm replacing a legacy application that (in the past) presented the user with a CICS green screen that provided 10 blank fields that contained OrderItems.  If the user had to enter 11 items, they would fill the 10 blank fields and request a new screen with 10 more blank fields.  Once they keyed the eleventh item, they would return to the previous screen and continue to key additional fields.  In the Windows version, I'm combining the old "green screens" into a Windows UI.  Since the average number of actual order items is only 1 or 2, I didn't want to waste screen space with 10 blank fields or emulate the way the older mainframe application worked.  Instead, I wanted to dynamically add as many blank fields as there are order items for that record without changing the relative location of the other fields.  In most high speed data entry applications, you really need to have the same data entry fields in the same place each and every time.  Hence the lame attempt as coded above.  The other fly in the soup is that some fields are so tightly related, they need to be treated as a group and I need that same ability to present the user with as many "groups" of related fields as needed.

    I'll take a peek at how much control I have over the layout of the datagrid like field spacing, the ability to scroll the datagrid, and if it will meet the requirements then I'll use that instead of trying to build a user control.

    Thanks!

    DeBug

    Thursday, March 22, 2007 4:31 PM
  • Iterate over your text boxes and add a Binding instance to each via TextBox.DataBindings.Add

    I did something similar to your needs when a client wanted 'form' based editing as opposed to table based editing. I iterateted over the DataColumn's in the data source (DataTable) and added captions and controls (text boxes etc) based on information gathered from each DataColumn.

    You don't need the extra blank fields - when you add a new row to the underlying data source the binding will clear out your bound controls.

    You navigate the source by adjusting CurrencyManager.Position, and again, the binding will automatically populate your bound controls.

    You can optionally handle parsing, formatting events on the Binding class to fine tune your data display.

    Thursday, March 22, 2007 6:55 PM
  • Dreedle,

    I'm not sure I follow your example completely but I'll put something together later this evening and try it out.  Stay tooned....

    DeBug

    Friday, March 23, 2007 1:52 PM