I didn't like any of the solutions to this problem until I came up with this one...
The solution is to bind the entire Child table to a bindingSource and that to a dataGridView. In this case the child table would be the courses that the soldier registered for.
Then, whenever a soldier is selected, store the selected row in a global variable, such as lastSelectedSoldierRow. Then, when that changes, you do a select on the table that connects the two. The registers table in this case. For example registerDataTable.Select("soldier_ID = " + lastSelectedSoldierRow.ID.ToString());
Take all those rows and add the course Ids to a globally declared stringBuilder. Whenever a different soldier is selected, add -1 to the stringBuilder as an initializer. Then, for each additional course ID added to the stringBuilder, add a comma to the stringBuilder before it. You'll end up with something like "1,2,3,4,5,6". Next, set the child table's bindingSource.Filter to a that string like so: Filter = "ID in (1,2,3,4,5)".
That will filter all the courses, down to the ones which belong to the soldier. Whenever a new course is added, append the ID to the stringBuilder and reset the filter.
Here's an example scrap of source code from my own project. It's messy, but may be helpful to somebody if the above wasn't enough.
StringBuilder settingsFilterSB = new StringBuilder();
private void dataGridViewComputers_SelectionChanged(object sender, EventArgs e)
{
if (this.dataGridViewComputers.SelectedRows.Count == 1 || this.dataGridViewComputers.SelectedCells.Count > 0)
{
object dataBoundItem;
if (this.dataGridViewComputers.SelectedRows.Count == 1)
dataBoundItem = this.dataGridViewComputers.SelectedRows[0].DataBoundItem;
else
dataBoundItem = this.dataGridViewComputers.Rows[this.dataGridViewComputers.SelectedCells[0].RowIndex].DataBoundItem;
lastSelectedPcRow = (CallistoDataSet.ComputerOrGroupRow)((DataRowView)dataBoundItem).Row;
settingsFilterSB = new StringBuilder();
settingsFilterSB.Append("-1");
int selectedPcId = lastSelectedPcRow.ID;
foreach(CallistoDataSet.ComputerOrGroup2SettingsRow row in this.callistoDataSet.ComputerOrGroup2Settings.Rows)
{
if(row.ComputerOrGroup_ID == selectedPcId)
settingsFilterSB.Append("," + row.ComputerSettings_ID.ToString());
}
this.computerSettingsBindingSource.Filter = "ID in (" + settingsFilterSB.ToString() + ")";