Binding Source Display, Dual column PK.

JaedenRuiner

Well-known member
Joined
Aug 13, 2007
Messages
340
Programming Experience
10+
I'm running over this one in my head, and keep trying different things but the logistics aren't quite coming clear, and the problem I think is a cool enigma to resolve.

I have ComboBox's that are bound to a BindingSource on the DataBindings to store their value into a DataSet/DataTable/Datarow. Pretty straightforward, while at the same time I have a BindingSource that provides the List Item values from a different related parent DataTable.

as one would expect:
VB.NET:
BOLEmailrCmb.DataBindings.Add(New System.Windows.Forms.Binding("SelectedValue", Me.bind_BOL, "Num", True))

BOLEmailCmb.DataSource = Bind_Email
BOLEmailCmb.DisplayMember = "Email_ID"
BOLEmailCmb.ValueMember = "Num"

Seemingly a simple correlation, that the DataBinding takes the value from the bind_BOL datasource and populates the selected value of the control, which then selects the appropriate Email_ID for that value from the Bind_Email binding source.
The complexity here is that the DataSource for the Bind_Email binding source is a Table that has a multi-column primary key, based on CustomerID and Num. So the "Num" column within the Bind_Email datasource is duplicated many times, and thus to get the "accurate" Email_ID value for the particular "Num" value of the current Bind_BOL record requires the additional value of the bind_Bol.Current("Customer") column.

Thus, I tried this:
VB.NET:
sub bind_Bol_CurrentChanged()
  BOLEmailCmb.DataSource.Filter = "Customer=" & bind_bol.Current.Row("Customer")
end sub
The problem is when I change from a record with customer ID 100107 to one with a customer ID of 100137, the filter update of the BOLEmailCmb.DataSource affects the BOLEmailCmb.DataBinding(0).DataSource into thinking the values have been changed, and the dataset thus believes its values have been dirtied.

Is there a way to define a binding source to base it's display value list off of two values instead of just one?
How could I handle this situation so that when the Bind_BOL bindingsource's position is changed to view a different record, the BOLEmailCmb reflects this change based upon Both the current Bind_BOL("Customer") column and the Bind_BOL("Num") column, preserving (saving) the "Num" value as the selected "ValueMember" to store for the BOLEmailCmb.DataBinding.

Thanks
 
Last edited:
Maybe add a composite column to your DataTable and set the DisplayMember to it?

VB.NET:
		Dim dc As New DataColumn("Composite", System.Type.GetType("System.String"))
		dc.Expression = "OrderID + '' + CustomerID"
		ds.Tables("Table").Columns.Add(dc)
 
Yea, that wasn't exactly what I was looking for, though it would be an additional workaround, since the display column is a computed column in the DB. What I ended up doing was listening to the CurrentChanged() event for the Data Bound BindingSource which changes from record to record as the user navigates the database/table. When it changes I update the ComboBox Item List DataSource with the filter on the customer property. It took a bit of maneuvering, and is somewhat of a hack, but I first found that by suspending/resuming the DataBinding bindingsource, i could prevent the dataset from thinking that it had been "updated" or any way changed while resetting the datasource criteria. After that I found that the suspend/resume reset the bindingsource position, so I needed to store it and restore it before/after the suspend/resume. I also found that the Resume binding caused the CurrentChanged event to fire concurrently so I had to put in the static to make sure that when I was "resuming" the binding it wouldn't try to reset the filter a second time.
this was my solution:
VB.NET:
   Private Sub bind_BOL_CurrentChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles bind_BOL.CurrentChanged 
      Static isBinding As Boolean = False 
      Try 
         If Not isBinding Then 
            isBinding = True 
            Dim drv As DataRowView = DirectCast(DirectCast(sender, BindingSource).Current, DataRowView) 
            If drv.IsValid Then
               dim i as integer = bind_BOL.Position
               bind_BOL.SuspendBinding() 
               DirectCast(Me.BOLEmailCmb.DataSource, BindingSource).Filter = "Customer=" & drv.Row("Customer").ToString.SingleQuote 
               bind_BOL.ResumeBinding()
               bind_BOL.Position = i
            End If 
            isBinding = False 
         End If 
      Catch ex As Exception 
         isBinding = False 
      End Try 
   End Sub
Thanks,
 

Latest posts

Back
Top