locked
Two bindings in the collection to bind to the same property RRS feed

  • Question

  • Dim objDataTable As DataTable

     Dim BS As BindingSource

    Public Sub PreviousSurveyRecords()

            'This works the first time.

            Dim objConnection As New OleDbConnection(connString)

            '~~~~~~~~~~~~~

            objDataTable = New DataTable

            BS = New BindingSource

            Dim strTableSQL As String = "SELECT * FROM TreatData WHERE (((TreatData.CustomerID)='" & lblCustomerID.Text & "'));"

            Dim objCommand As New OleDbCommand(strTableSQL, objConnection)

            Dim objDataAdapter As New OleDbDataAdapter(objCommand)

            'Fill data table

            objDataAdapter.Fill(objDataTable)

            'Close connection and releast resources

            objConnection.Close()

            objConnection.Dispose()

            objConnection = Nothing

            objCommand.Dispose()

            objCommand = Nothing

            objDataAdapter.Dispose()

            objDataAdapter = Nothing

                        'Load data into DataTable use BindingSource to scroll thru Data

            BS.DataSource = objDataTable

            lblSurveyNum.DataBindings.Add("Text", BS, "TreatNum")

            TextBox1.DataBindings.Add("Text", BS, "Recreation")

            TextBox2.DataBindings.Add("Text", BS, "Sleep")

            TextBox3.DataBindings.Add("Text", BS, "Personal")

            TextBox4.DataBindings.Add("Text", BS, "Travel")

    End Sub

                        This is my attempt to clear out the "BindingSource" and the "DataTable" when

                   I leave this form.             

    Private Sub btnReturnToStartForm_Click(sender As Object, e As EventArgs) Handles btnReturnToStart.Click

            pmiUtilities.Disable4Buttons()

            pmiUtilities.btn4Enabled()

            'objDataTable.Clear()

            'objDataTable.Dispose()

            'objDataTable = Nothing

            BS.Dispose()

            BS = Nothing

            frmStart.txtCustomerID.Clear()

            frmStart.txtFirstName.Clear()

            frmStart.txtLastName.Clear()

            frmStart.Show()

            frmStart.txtCustomerID.Focus()

            Me.Hide()

        End Sub

    When I go back to the Start Form and try to show a different customer (new data) I get this error:

                   "This causes two bindings in the collection to bind to the same property."

    Friday, November 27, 2015 12:06 PM

Answers

  • This may not be the best solution to my problem BUT it works

    I changed Me.Hide to Me.Close on this form

    then on the start form I added frmReview.Refresh

    That cleared out the Binding Source and the DataTable.

    If there is a better solution I would like to use that.

    Hi Jay,

    We'd have to see more context of how the multiple forms work together to say if there was a better way to achieve your goal.  I suppose it would also help to have a clear explanation of what that goal is.  :P

    You probably just need a small refactoring so that this code:

    lblSurveyNum.DataBindings.Add("Text", BS, "TreatNum")
    TextBox1.DataBindings.Add("Text", BS, "Recreation")
    TextBox2.DataBindings.Add("Text", BS, "Sleep")
    TextBox3.DataBindings.Add("Text", BS, "Personal")
    TextBox4.DataBindings.Add("Text", BS, "Travel")
    
    ...only happens once when the form containing those controls is loaded.  After that all you need to do is refresh the databindings when the underlying datasource experiences changes (or make those changes through a BindingSource component).


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    • Marked as answer by Jay8000 Saturday, November 28, 2015 3:33 AM
    Friday, November 27, 2015 9:21 PM
  • Jay,

    To add to what Reed said, if you're using a BindingSource and if the data behind the BindingSource changes, be sure that you call .ResetBindings(False). That will force the BindingSource to reread the .DataSource of it.

    If you set it up through the wizard, that might not be needed. I don't remember now, but I think it is, so don't duplicate work of course. ;-)


    If I had eight hours to chop down a tree, I'd spend six sharpening my axe. -- Abraham Lincoln

    • Marked as answer by Jay8000 Saturday, November 28, 2015 3:34 AM
    Friday, November 27, 2015 9:35 PM

All replies

  • if you first start removing all those

    .. = nothing

    and 

    xx.dispose 

    then your code becomes much readable. 

    It serves in your code absolutely nothing.


    Success
    Cor

    Friday, November 27, 2015 12:26 PM
  • This may not be the best solution to my problem BUT it works

    I changed Me.Hide to Me.Close on this form

    then on the start form I added frmReview.Refresh

    That cleared out the Binding Source and the DataTable.

    If there is a better solution I would like to use that.

    Friday, November 27, 2015 9:10 PM
  • This may not be the best solution to my problem BUT it works

    I changed Me.Hide to Me.Close on this form

    then on the start form I added frmReview.Refresh

    That cleared out the Binding Source and the DataTable.

    If there is a better solution I would like to use that.

    Hi Jay,

    We'd have to see more context of how the multiple forms work together to say if there was a better way to achieve your goal.  I suppose it would also help to have a clear explanation of what that goal is.  :P

    You probably just need a small refactoring so that this code:

    lblSurveyNum.DataBindings.Add("Text", BS, "TreatNum")
    TextBox1.DataBindings.Add("Text", BS, "Recreation")
    TextBox2.DataBindings.Add("Text", BS, "Sleep")
    TextBox3.DataBindings.Add("Text", BS, "Personal")
    TextBox4.DataBindings.Add("Text", BS, "Travel")
    
    ...only happens once when the form containing those controls is loaded.  After that all you need to do is refresh the databindings when the underlying datasource experiences changes (or make those changes through a BindingSource component).


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    • Marked as answer by Jay8000 Saturday, November 28, 2015 3:33 AM
    Friday, November 27, 2015 9:21 PM
  • Jay,

    To add to what Reed said, if you're using a BindingSource and if the data behind the BindingSource changes, be sure that you call .ResetBindings(False). That will force the BindingSource to reread the .DataSource of it.

    If you set it up through the wizard, that might not be needed. I don't remember now, but I think it is, so don't duplicate work of course. ;-)


    If I had eight hours to chop down a tree, I'd spend six sharpening my axe. -- Abraham Lincoln

    • Marked as answer by Jay8000 Saturday, November 28, 2015 3:34 AM
    Friday, November 27, 2015 9:35 PM
  • Jay,

    To add to what Reed said, if you're using a BindingSource and if the data behind the BindingSource changes, be sure that you call .ResetBindings(False). That will force the BindingSource to reread the .DataSource of it.

    If you set it up through the wizard, that might not be needed. I don't remember now, but I think it is, so don't duplicate work of course. ;-)


    If I had eight hours to chop down a tree, I'd spend six sharpening my axe. -- Abraham Lincoln

    Ideally you want to manipulate the data such that calling that method isn't necessary.  Sometimes that means that extra work is needed if the underlying data object doesn't already provide change notification (you have to then implement INotifyPropertyChanged and maybe collection related interfaces as well depending on the objects being used).  Since this scenario is working with DataRow objects it should be possible to make the changes and have everything show up properly without needing to reset the bindings.  Its all a matter of making sure everyone is using the same binding manager...

    Sometimes there's no (easy) way around it though.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Friday, November 27, 2015 10:21 PM

  • Ideally you want to manipulate the data such that calling that method isn't necessary.  Sometimes that means that extra work is needed if the underlying data object doesn't already provide change notification (you have to then implement INotifyPropertyChanged and maybe collection related interfaces as well depending on the objects being used).  Since this scenario is working with DataRow objects it should be possible to make the changes and have everything show up properly without needing to reset the bindings.  Its all a matter of making sure everyone is using the same binding manager...

    Sometimes there's no (easy) way around it though.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    I don't use databases, so when I use my own object binding, there's really no other way.

    The BindingSource does have its own events and .ListChanged is one of them, but I've never really seen much use for any of the events. Obviously I know when the collection has changed!

    You're likely right though, it's probably not needed.


    If I had eight hours to chop down a tree, I'd spend six sharpening my axe. -- Abraham Lincoln

    Friday, November 27, 2015 10:26 PM
  • I don't use databases, so when I use my own object binding, there's really no other way.

    That's when you have to implement the associated interfaces according to your object model. With all of the right hints in place, all of the features of data binding will work as expected, automatically.

    However, it can require that you add a ton of boilerplate to your code.  Maybe one day (nudge, nudge, wink, wink, say no more) we'll see an improved methodology for implementing commonly needed component model interfaces without all the boilerplate.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Friday, November 27, 2015 10:53 PM