You can use DataView
as a data source for your comboboxes, since this allows you to filter rows based on a criterion (via the RowFilter
property). I'll show a simple example involving two comboboxes used for selecting a country and a town in that country.
First, set up some data to be used:
// set up DataTable with countries:
countriesTable = new DataTable("Countries");
countriesTable.Columns.Add("CountryID", typeof(int));
countriesTable.Columns.Add("CountryName", typeof(string));
countriesTable.Rows.Add(1, "England");
countriesTable.Rows.Add(2, "Spain");
...
// set up DataTable with towns:
townsTable = new DataTable("Towns");
townsTable.Columns.Add("TownID", typeof(int));
townsTable.Columns.Add("TownName", typeof(string));
townsTable.Columns.Add("CountryID", typeof(int)); // <-- this is a foreign key
townsTable.Rows.Add(1, "London", 1);
townsTable.Rows.Add(2, "Brighton", 1);
townsTable.Rows.Add(3, "Barcelona", 2);
...
Next, data-bind the comboboxes to the data:
// bind countries to country combobox:
countryComboBox.DataSource = countriesTable;
countryComboBox.DisplayMember = "CountryName";
countryComboBox.ValueMember = "CountryID";
// bind towns to town combobox:
townsView = new DataView(townsTable, "CountryID = 1", ...); // use foreign key
townComboBox.DataSource = townsView; // in a row filter
townComboBox.DisplayMember = "TownName";
townComboBox.ValueMember = "TownID";
Finally, whenever another country is selected in the country combobox, update the row filter:
private void countryComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
...
townsView.RowFilter = string.Format("CountryID = {0}",
countryComboBox.SelectedValue);
}
I believe you could automate this last step using databinding and a custom Format
event handler, but I won't go into details.