I have a DataGridView that has a DataGridViewComboBoxColumn column. I want to bind this column to a many-to-many relationship or "junction table" (MS Access terminology) and am having trouble getting things to work.
I would like the DataGridViewComboBoxColumn to show the ObjectType (DisplayMember) from the ObjectTypes datatable in the control's drop-down list, but have the control bound to the ObjectTypeID (ValueMember) in the RevisionObjects datatable. The RevisionObjects datatable would contain the ObjectType, not the ObjectType after the user makes their selection.
As the user moves between records in the RevisionNotes datatable, the grid should show 2 columns: ObjectType (e.g., "Form", "Module", "Class", etc.) and ObjectName ("Form1", "Module1", "Class1", etc.).
Here is how I've set up the Relations:
Code:
'RevisionNote and RevisionObjects
dsMain.Relations.Add(name:="RevisionNote_RevisionObjects", parentColumn:=dsMain.Tables("RevisionNotes").Columns("RecID"), childColumn:=dsMain.Tables("RevisionObjects").Columns("NoteID"))
fkc = dsMain.Relations("RevisionNote_RevisionObjects").ChildKeyConstraint
fkc.DeleteRule = Rule.Cascade
fkc.UpdateRule = Rule.Cascade
fkc.AcceptRejectRule = AcceptRejectRule.Cascade
'ObjectType and RevisionObjects
dsMain.Relations.Add(name:="ObjectType_RevisionObjects", parentColumn:=dsMain.Tables("ObjectTypes").Columns("RecID"), childColumn:=dsMain.Tables("RevisionObjects").Columns("ObjectTypeID"))
fkc = dsMain.Relations("ObjectType_RevisionObjects").ChildKeyConstraint
fkc.DeleteRule = Rule.SetNull '...when an ObjectTypes table record is deleted, set the related child RevisionObjects table's RevisionObjects.ObjectTypeID = DBNull.Value (this field is not required and IsNullable)
fkc.UpdateRule = Rule.Cascade
fkc.AcceptRejectRule = AcceptRejectRule.Cascade
Here is how I'm configuring the DataGridView columns:
Code:
With dgvObjects
Dim col0 As New DataGridViewTextBoxColumn
With col0
.DataPropertyName = "RecID"
.Name = "RecID"
.HeaderText = "RecID"
.Visible = False
End With
.Columns.Add(col0)
Dim col1 As New DataGridViewComboBoxColumn
With col1
col1.DisplayMember = "ObjectName"
col1.ValueMember = "ObjectTypeID"
col1.HeaderText = "Type"
col1.DataSource = bsRevisionObjects
.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter
.DefaultCellStyle.Alignment = DataGridViewContentAlignment.TopLeft
.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells
.SortMode = DataGridViewColumnSortMode.Automatic '...sorting glyph is automatically displayed in the column header
End With
.Columns.Add(col1)
Dim col2 As New DataGridViewTextBoxColumn
With col2
.DataPropertyName = "ObjectName"
.Name = "Name"
.HeaderText = "Name"
.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleLeft
.DefaultCellStyle.Alignment = DataGridViewContentAlignment.TopLeft
.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
.SortMode = DataGridViewColumnSortMode.Automatic '...sorting glyph is automatically displayed in the column header
End With
.Columns.Add(col2)
End With
Here's how I'm binding the data:
Code:
With bsObjects
.DataSource = Nothing
.DataMember = "ObjectTypes" '...bind to relationship (before setting the DataSource property, which fires the PositionChanged() event of the BindingSource)
.DataSource = dsMain '...fires the BindingSource's PositionChanged() event
.Sort = "ObjectType"
End With
If flgDebug Then Debug.WriteLine("bsObjects datasource has " & bsObjects.Count & " items.")
With bsRevisionObjects
.DataSource = Nothing
.DataMember = "ObjectType_RevisionObjects" '...bind to relationship (before setting the DataSource property, which fires the PositionChanged() event of the BindingSource)
.DataSource = bsObjects '...fires the BindingSource's PositionChanged() event
.Sort = "ObjectName"
End With
If flgDebug Then Debug.WriteLine("bsRevisionObjects datasource has " & bsRevisionObjects.Count & " items.")
dgvObjects.DataSource = bsRevisionObjects
When this code executes, the DataGridView shows every column from the datatable (all 6 from the RevisionObjects datable plus the 2 that I explicitly configured above), even though I have set the grid's AutoGenerateColumns = False.
I need some guidance to get this figured out and would appreciate some help.
Last edited by Mark@SF; Apr 28th, 2020 at 01:10 AM.