Reputation: 69
I'm currently populating combobox with list from db query like this:
private List<ExerciseAndVideo> GetExerciseVideoComboBoxListFromDB()
{
List<ExerciseAndVideo> exerciseList = new List<ExerciseAndVideo>();
con = new SqlConnection("my db path etc");
cmd = new SqlCommand();
con.Open();
cmd.Connection = con;
cmd.CommandText = "SELECT nome, link_video, gruppo_muscolare FROM Esercizi ORDER BY nome ASC";
dr = cmd.ExecuteReader();
while (dr.Read())
{
ExerciseAndVideo item = new ExerciseAndVideo();
item.Esercizio = dr.GetString(0);
item.Video = dr.GetString(1);
item.Gruppo = dr.GetString(2);
exerciseList.Add(item);
}
con.Close();
return exerciseList;
}
public class ExerciseAndVideo
{
public string Esercizio { get; set; }
public string Video { get; set; }
public string Gruppo { get; set; }
}
What I'm trying to do now is to add another combobox in the dgv for filter the results of the exercise list.
I've added the combo like this:
dataGridView1.Columns.Add(GetGroupComboBoxColumn(GrList));
private List<GroupList> GetGroupComboBoxListFromDB()
{
List<GroupList> GrList = new List<GroupList>();
GrList.Add(new GroupList { Gruppo = "quads" });
GrList.Add(new GroupList { Gruppo = "hamstring" });
GrList.Add(new GroupList { Gruppo = "gluteus" });
return GrList;
}
How can I do this?
I want that when in the combo1 is selected "quads", in the combo 2 I see only the exercises for quads.
EDIT
Here there are the events that get fire on the dgv combos:
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (dataGridView1.Columns[dataGridView1.CurrentCell.ColumnIndex].Name == "Esercizio")
{
curCombo = e.Control as ComboBox;
if (curCombo != null)
{
curCombo.SelectedIndexChanged -= new EventHandler(curCombo_SelectedIndexChanged);
curCombo.SelectedIndexChanged += new EventHandler(curCombo_SelectedIndexChanged);
}
}
}
private void curCombo_SelectedIndexChanged(object sender, EventArgs e)
{
if (curCombo != null && curCombo.SelectedValue != null)
{
ExerciseAndVideo selectedExercise = (ExerciseAndVideo)curCombo.SelectedItem;
dataGridView1.CurrentRow.Cells["Video"].Value = selectedExercise.Video;
dataGridView1.CurrentRow.Cells["Gruppo"].Value = selectedExercise.Gruppo;
}
}
private void dataGridView1_CellLeave(object sender, DataGridViewCellEventArgs e)
{
if (dataGridView1.Columns[e.ColumnIndex].Name == "Esercizio")
{
if (curCombo != null)
{
curCombo.SelectedIndexChanged -= new EventHandler(curCombo_SelectedIndexChanged);
}
}
}
And Here how the combos get datasource:
private DataGridViewComboBoxColumn GetGroupComboBoxColumn(List<GroupList> GrList)
{
DataGridViewComboBoxColumn cbCol = new DataGridViewComboBoxColumn();
cbCol.HeaderText = "Zona";
cbCol.Name = "Zona";
cbCol.DisplayMember = "Zona";
cbCol.DataSource = GrList;
cbCol.Width = 100;
return cbCol;
}
private DataGridViewComboBoxColumn GetExcerciseComboBoxColumn(List<ExerciseAndVideo> exerciseList)
{
DataGridViewComboBoxColumn cbCol = new DataGridViewComboBoxColumn();
cbCol.HeaderText = "Esercizio";
cbCol.Name = "Esercizio";
cbCol.DisplayMember = "Esercizio";
// if I use this string works fine
string selectedGroup = "quadricipiti";
var filteredList = exerciseList.Where(x => x.Gruppo == selectedGroup).ToList();
cbCol.DataSource = filteredList;
cbCol.Width = 140;
return cbCol;
}
EDIT 2
I edit the curCombo_SelectedIndexChanged event as suggest but I'm getting error on exerciseList because not exist in the function:
private void curCombo_SelectedIndexChanged(object sender, EventArgs e)
{
if (curCombo != null && curCombo.SelectedValue != null)
{
ExerciseAndVideo selectedExercise = (ExerciseAndVideo)curCombo.SelectedItem;
dataGridView1.CurrentRow.Cells["Video"].Value = selectedExercise.Video;
dataGridView1.CurrentRow.Cells["Gruppo"].Value = selectedExercise.Gruppo;
string selectedGroup = Convert.ToString((GroupList)SelectedCombo.SelectedItem);
DataGridViewComboBoxCell Esercizi = (DataGridViewComboBoxCell)(dataGridView1.CurrentRow.Cells["Esercizi"]);
var filteredList = exerciseList.Where(x => x.Gruppo == selectedGroup).ToList();
Esercizi.DataSource = filteredList;
}
}
EDIT 3
After correcting the list code to make it work as global, I get no error but I'm not be able to pick the selected value from combo 1 as selected group.
If I use a string like "quads" or other everything works fine, else if I try to pick the value from combo1, I get a blank list on combo 2.
Here some code I tried for get the value from combo 1:
string selectedGroup = Convert.ToString(dataGridView1.CurrentRow.Cells["Zona"]);
string selectedGroup = SelectedCombo.SelectedItem.ToString();
string selectedGroup = Convert.ToString((GroupList)SelectedCombo.SelectedItem);
LAST EDIT
Here what I found is working to get the value from combo 1:
string selectedGroup = Convert.ToString(dataGridView1.CurrentRow.Cells[0].FormattedValue.ToString());
The problem now is that to make working the filter, I must select 2 time the value in the combo 1.
So for example, I select "quads" in combo 1 and I get a blank list in combo 2. I select "quads" another time and I get the filtered result.
I think the problem can be in the event but I don't see errors:
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (dataGridView1.Columns[dataGridView1.CurrentCell.ColumnIndex].Name == "Esercizio")
{
curCombo = e.Control as ComboBox;
if (curCombo != null)
{
curCombo.SelectedIndexChanged -= new EventHandler(curCombo_SelectedIndexChanged);
curCombo.SelectedIndexChanged += new EventHandler(curCombo_SelectedIndexChanged);
}
}
if (dataGridView1.Columns[dataGridView1.CurrentCell.ColumnIndex].Name == "Zona")
{
curCombo = e.Control as ComboBox;
if (curCombo != null)
{
curCombo.SelectedIndexChanged -= new EventHandler(ComboBox_SelectedIndexChanged);
curCombo.SelectedIndexChanged += new EventHandler(ComboBox_SelectedIndexChanged);
}
}
}
private void curCombo_SelectedIndexChanged(object sender, EventArgs e)
{
if (curCombo != null && curCombo.SelectedValue != null)
{
ExerciseAndVideo selectedExercise = (ExerciseAndVideo)curCombo.SelectedItem;
dataGridView1.CurrentRow.Cells["Video"].Value = selectedExercise.Video;
dataGridView1.CurrentRow.Cells["Gruppo"].Value = selectedExercise.Gruppo;
}
}
private void ComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (curCombo.SelectedValue != null)
{
string selectedGroup = Convert.ToString(dataGridView1.CurrentRow.Cells[0].FormattedValue.ToString());
DataGridViewComboBoxCell Esercizi = (DataGridViewComboBoxCell)(dataGridView1.CurrentRow.Cells["Esercizio"]);
// string selectedGroup = "femorali";
var filteredList = exerciseList.Where(x => x.Gruppo == selectedGroup).ToList();
Esercizi.DataSource = filteredList;
}
}
private void dataGridView1_CellLeave(object sender, DataGridViewCellEventArgs e)
{
if (dataGridView1.Columns[e.ColumnIndex].Name == "Esercizio")
{
if (curCombo != null)
{
curCombo.SelectedIndexChanged -= new EventHandler(curCombo_SelectedIndexChanged);
}
}
if (dataGridView1.Columns[e.ColumnIndex].Name == "Zona")
{
if (curCombo != null)
{
curCombo.SelectedIndexChanged -= new EventHandler(ComboBox_SelectedIndexChanged);
}
}
}
Upvotes: 0
Views: 629
Reputation: 9469
From the long back and forth in comments. I have a solution below that should work as you describe. Before I start I would like to suggest you take more care when you post a question. Initially when you posted this question, there were many-many details left out that would have avoided the unnecessary extended comments that you see. The more details you leave out and the more questions others have to ask to understand your question, the less chance you have of getting your question answered.
In the future, I suggest you provide all the needed info and certainly edit your question to add any pertinent info if it becomes obvious that it is needed. The more work others have to do to help you, the less chance you have of getting any help at all much less an answer. Do yourself a favor and take that extra step to make sure your question is fully understandable and better yet reproducible… I promise you will not regret it.
Moving on, given the picture below, I assume this is similar to what you have posted.
The user can select and change a “Zone” combo box item. When this happens, is what we want to do is “filter” the “Exercise” columns combo box cell to contain ONLY exercises that are in the selected Zone. THEN, if the user selects an exercise from the Exercise combo box cell, THEN, the matching “Video” link for that exercise is displayed in the “Video” cell on that row. Hopefully this is correct.
Observations lead to some other assumed behaviors.
IF a row has a selected Zone and a selected Exercise and the Video cell displays the video link for the exercise… then… IF the user changes the “ZONE” value for that row, THEN the code will CLEAR the Exercise and Video cells since those values MAY NOT necessarily belong to the newly selected Zone.
Assuming the Zone combo box cell is “empty”… IF the user attempts to select an Exercise from the Exercise combo box BEFORE the Zone value has been set for that row… THEN… we want the Exercise combo box to contain NO values since the Zone has not been selected yet. In other words, the Exercise combo box will not fill with values until the user selects a Zone.
The code below uses the above assumptions and clears the Exercise and Video values when the Zone changes and prevents the user from selecting an Exercise before a Zone has been selected.
If you create a new winform solution and drop a DataGridView
onto the form, you should be able to follow along to complete this example step by step. Below is some code and classes to help with test data and building the grid.
First the two classes we will use for the combo box columns. Both are simple and fairly straight forward.
public class ExerciseAndVideo {
public string Exercise { get; set; }
public string Video { get; set; }
public string ZoneName { get; set; }
}
public class Zone {
public string ZoneName { get; set; }
}
Some additional code to fill the global variables ExerciseList
and ZoneList
with some test data for the combo boxes…
private void SetExerciseListFromDB() {
ExerciseList = new List<ExerciseAndVideo>();
ExerciseList.Add(new ExerciseAndVideo { Exercise = "-", ZoneName = "-", Video = "" });
ExerciseList.Add(new ExerciseAndVideo { Exercise = "Exercise 1", ZoneName = "quads", Video = "Video 1" });
ExerciseList.Add(new ExerciseAndVideo { Exercise = "Exercise 2", ZoneName = "gluteus", Video = "Video 2" });
ExerciseList.Add(new ExerciseAndVideo { Exercise = "Exercise 3", ZoneName = "quads", Video = "Video 3" });
ExerciseList.Add(new ExerciseAndVideo { Exercise = "Exercise 4", ZoneName = "hamstring", Video = "Video 4" });
ExerciseList.Add(new ExerciseAndVideo { Exercise = "Exercise 5", ZoneName = "quads", Video = "Video 5" });
ExerciseList.Add(new ExerciseAndVideo { Exercise = "Exercise 6", ZoneName = "hamstring", Video = "Video 6" });
ExerciseList.Add(new ExerciseAndVideo { Exercise = "Exercise 7", ZoneName = "quads", Video = "Video 7" });
ExerciseList.Add(new ExerciseAndVideo { Exercise = "Exercise 8", ZoneName = "gluteus", Video = "Video 8" });
}
private void SetZoneListFromDB() {
ZoneList = new List<Zone>();
ZoneList.Add(new Zone { ZoneName = "-" });
ZoneList.Add(new Zone { ZoneName = "quads" });
ZoneList.Add(new Zone { ZoneName = "hamstring" });
ZoneList.Add(new Zone { ZoneName = "gluteus" });
}
NOTE: In the above code you may notice that each list of exercises and zones has an additional item added that is used to represent a NO CHOICE by the user….
ExerciseList.Add(new ExerciseAndVideo { Exercise = "-", ZoneName = "-", Video = "" });
and
ZoneList.Add(new Zone { ZoneName = "-" });
We could do without these “blank” (NO choice) values; however, we will need a way to set the Exercise combo box to some “blank” value when a different Zone is selected. You could set a default value like the first exercise in the list and this would work. The main point here is that if we DO NOT set the Exercise value to a value that BELONGS to the “filtered” version of the “filtered” exercises… you will get the grid’s DataError
complaining about the value in the cell is not a valid value in the combo boxes list of items.
This applies when the user “changes” a Zone combo box value and the Exercise cell already contains a value from the previously set Zone value. If we do not change the Exercise value to “something” that is in the newly filtered version and simply leave the exercise value with its old value… then we will get the grid’s DataError
.
This is the logic behind adding a “Blank” No-choice value to the Exercise list. When we filter the list, we will ADD this “Blank” value to the list and then set the Exercise value to that “blank” value when the Zone changes. This way we can almost guarantee that we will avoid the grid’s DataError
because of an invalid value in the exercise cell. There are other ways around this, however, I have found this “blank” non-choice value makes things much easier when dealing with combo boxes that are related to each other. I hope that makes sense.
Next the code that manually sets up the grid’s columns including the Zone and Exercise combo box columns. You may want to consider giving the grid a DataSource
… more on this at the end.
private void AddColumnsToGrid() {
DataGridViewComboBoxColumn cbCol = GetComboBoxColumn("Zone", "Zone", "ZoneName", 100);
cbCol.DataSource = ZoneList;
dataGridView1.Columns.Add(cbCol);
cbCol = GetComboBoxColumn("Exercise", "Exercise", "Exercise", 140);
cbCol.DataSource = ExerciseList;
dataGridView1.Columns.Add(cbCol);
dataGridView1.Columns.Add(GetTextBoxColumn("Serie", "serie"));
dataGridView1.Columns.Add(GetTextBoxColumn("Ripetizioni", "ripetizioni"));
dataGridView1.Columns.Add(GetTextBoxColumn("Recupero", "recupero"));
dataGridView1.Columns.Add(GetTextBoxColumn("Time under tension", "tut"));
dataGridView1.Columns.Add(GetLinkColumn("Video", "Video"));
dataGridView1.Columns.Add(GetTextBoxColumn("Note", "note"));
}
private DataGridViewComboBoxColumn GetComboBoxColumn(string headertext, string name, string displayMember, int width) {
DataGridViewComboBoxColumn cbCol = new DataGridViewComboBoxColumn();
cbCol.HeaderText = headertext;
cbCol.Name = name;
cbCol.DisplayMember = displayMember;
cbCol.Width = width;
return cbCol;
}
private DataGridViewTextBoxColumn GetTextBoxColumn(string headerText, string name) {
DataGridViewTextBoxColumn col = new DataGridViewTextBoxColumn();
col.HeaderText = headerText;
col.Name = name;
return col;
}
private DataGridViewLinkColumn GetLinkColumn(string headerText, string name) {
DataGridViewLinkColumn col = new DataGridViewLinkColumn();
col.HeaderText = headerText;
col.Name = name;
return col;
}
If we run the code now, it will look like the picture above. The user can select any Zone and any Exercise. The filtering for the Exercise combo box has not been implemented nor has the setting of the Video cell. So you should see all the Zones and all the Exercises in the combo boxes regardless which Zone is selected.
Next we will apply the “filtering” to the Exercise combo box when the user changes the Zone combo box value. The overall approach goes something like this… First we want to create a global regular ComboBox
variable we will call CurCombo
. Then we will wire up the grid’s EditingControlShowing
event. This event fires when the user clicks into a grid cell and starts editing the cell. Bear in mind… this event fires BEFORE the user actually makes any changes to the cell. In this event we will look to see if the edited cell is a Zone cell. IF the edited cell IS a Zone cell THEN… all we want to do is cast the grid’s combo box cell to our global CurCombo
variable. This will look something like…
CurCombo = e.Control as ComboBox;
Where e
is a passed in DataGridViewEditingControlShowingEventArgs
variable. It will allow us to cast the cell to a regular combo box. Then, we will wire up the CurCombo
’s SelectedIndexChanged
event then exit and wait for the user to change the combo box’s index.
When the user does indeed change the Zone combo boxes index, and the combo boxes SelectedIndexChanged
event fires… then we will know that we need to “filter” the Exercise combo box based on the selected Zone.
To further complicate things… IF the user changes one of the Exercise combo boxes, then we want to update the Video cell to display the link to the selected Video. We could create another ComboBox
and do the same thing as we did with the Zone combo box, however, we know that the user can NOT select BOTH combo boxes at the same time. So we can use the same CurCombo
variable for both combo boxes. HOWEVER… we need to make sure and UN-WIRE the CurCombo
’s SelectedIndexChanged
event when the user leaves the cell. Otherwise, BOTH events will start firing when either combo box is changed.
Considering that BOTH combo boxes are going to fire the grid’s EditingControlShowingEvent
event, we need to take an extra step if the combo box is an Exercise combo box. Before we wire up the CurCombo
’s SelectedIndexChanged
event, we want to check and see if the Zone combo box has a value. If the Zone combo box has no value, then we do NOT want the Exercise combo box to contain any values other than the blank no-choice value. We want the user to select a Zone first.
Therefore if the Exercise combo box is edited and the Zone combo box cell is not empty then we simply wire up the CurCombo
’s SelectedIndexChanged
event to point to a different event method that will update the video cell, then exit and wait for the user to change an Exercise value. If the Zone cell IS EMPTY, then we will filter the Exercise combo box to contain ONLY our BLANK Non-choice value AND we will NOT wire up the CurCombo
event since the user cannot select an exercise anyway.
It looks like a lot of code; however I peppered the code with some debug statements so we can see in the Output window when the event is entered and when it exits along with showing which event gets wired up. This may help in debugging and I would remove the debugging statements once you get it working fully.
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) {
Debug.WriteLine("DGV_EditingControlShowing <- Enter");
if (dataGridView1.Columns[dataGridView1.CurrentCell.ColumnIndex].Name == "Exercise") {
if (dataGridView1.CurrentRow.Cells["Zone"].Value != null && // <- Zone is not null
!string.IsNullOrEmpty(dataGridView1.CurrentRow.Cells["Zone"].Value.ToString()) && // <- Zone is not an empty string
dataGridView1.CurrentRow.Cells["Zone"].Value.ToString() != "-") { // <= Zone is not "-" blank value
CurCombo = e.Control as ComboBox;
if (CurCombo != null) {
Debug.WriteLine("----------Wiring up Exercise combo box");
CurCombo.SelectedIndexChanged -= new EventHandler(ExerciseComboBox_SelectedIndexChanged);
CurCombo.SelectedIndexChanged += new EventHandler(ExerciseComboBox_SelectedIndexChanged);
}
}
else {
// NO Zone is selected - set the Exercise combo box item list to our single blank value
DataGridViewComboBoxCell ExerciseCell = (DataGridViewComboBoxCell)(dataGridView1.CurrentRow.Cells["Exercise"]);
var filteredList = ExerciseList.Where(x => x.ZoneName == "-").ToList();
Debug.WriteLine("----------Zone is empty filtering Exercise combo box to single blank value");
ExerciseCell.DataSource = filteredList;
}
}
else {
if (dataGridView1.Columns[dataGridView1.CurrentCell.ColumnIndex].Name == "Zone") {
CurCombo = e.Control as ComboBox;
if (CurCombo != null) {
Debug.WriteLine("----------Wiring up Zone combo box");
CurCombo.SelectedIndexChanged -= new EventHandler(ZoneComboBox_SelectedIndexChanged);
CurCombo.SelectedIndexChanged += new EventHandler(ZoneComboBox_SelectedIndexChanged);
}
}
}
Debug.WriteLine("DGV_EditingControlShowing -> Leave");
}
Next we need to implement the ExerciseComboBox_SelectedIndexChanged
and the ZoneComboBox_SelectedIndexChanged
event methods… Again debugging statements are added to help in debugging. It should be noted, that if we use a List<ExerciseAndVideo>
as a DataSource
to the combo box column, then instead of trying to get the combo boxes value directly from the grids cell… I suggest you get the ExerciseAndVideo
object directly from the combo boxes SelectedItem
property. We should be able to cast it like…
ExerciseAndVideo EandV = (ExerciseAndVideo)CurCombo.SelectedItem;
And
Zone selectedZone = (Zone)CurCombo.SelectedItem;
This should make it easier to get the newly selected value in the grids cell.
private void ExerciseComboBox_SelectedIndexChanged(object sender, EventArgs e) {
Debug.WriteLine("ExerciseComboBox_SelectedIndexChanged <- Enter");
if (CurCombo != null) {
ExerciseAndVideo EandV = (ExerciseAndVideo)CurCombo.SelectedItem;
dataGridView1.CurrentRow.Cells["Video"].Value = EandV.Video;
}
Debug.WriteLine("ExerciseComboBox_SelectedIndexChanged -> Leave");
}
private void ZoneComboBox_SelectedIndexChanged(object sender, EventArgs e) {
Debug.WriteLine("ZoneComboBox_SelectedIndexChanged <- Enter");
if (CurCombo.SelectedValue != null) {
Zone selectedZone = (Zone)CurCombo.SelectedItem;
DataGridViewComboBoxCell ExerciseCell = (DataGridViewComboBoxCell)(dataGridView1.CurrentRow.Cells["Exercise"]);
var filteredList = ExerciseList.Where(x => x.ZoneName == selectedZone.ZoneName || x.ZoneName == "-").ToList();
Debug.WriteLine("----------Exercises combo filtered");
ExerciseCell.DataSource = filteredList;
dataGridView1.CurrentRow.Cells["Exercise"].Value = "-";
dataGridView1.CurrentRow.Cells["Video"].Value = "";
}
Debug.WriteLine("ZoneComboBox_SelectedIndexChanged -> Leave");
}
Almost done… If we run the code now, you will be able to change the Zone combo box, however, if we change a Zone combo box value then click on one of the Exercise combo boxes you will get a casting error in the ZoneComboBox_SelectedIndexChanged
method. The reason for the error is that when we clicked on the Zone combo box, the global CurCombo
’s SelectedIndexChanged
gets wired up to point to the method that filters the Exercise combo box. Therefore, when the Exercise combo is selected, the code will fail and throw a casting exception when it tries to cast the combo box to an Zone
object and it is really an ExerciseAndVideo
object.
This relates to the comment earlier where we MUST make sure and UN-WIRE the CurCombo
’s SelectedIndexChanged
event when the user LEAVES the cell. The approach used in this example is to simply wire up the grid’s CellLeave
event, and in that event we will check to see which cell is ending its edit (Zone or ExerciseAndVideo), then UN-WIRE the CurCombo
’s SelectedIndexChanged
event. The grid’s CellLeave
event may look something like.
private void dataGridView1_CellLeave(object sender, DataGridViewCellEventArgs e) {
Debug.WriteLine("DGV_CellLeave <- Enter");
if (CurCombo != null) {
string colName = dataGridView1.Columns[e.ColumnIndex].Name;
switch (colName) {
case "Exercise":
Debug.WriteLine("----------UN-Wiring Exercise combo box");
CurCombo.SelectedIndexChanged -= new EventHandler(ExerciseComboBox_SelectedIndexChanged);
break;
case "Zone":
Debug.WriteLine("----------UN-Wiring Zone combo box");
CurCombo.SelectedIndexChanged -= new EventHandler(ZoneComboBox_SelectedIndexChanged);
break;
default:
break;
}
}
Debug.WriteLine("DGV_CellLeave -> Leave");
}
And finally, the grid’s DataError
event is wired up to help in debugging.
private void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e) {
MessageBox.Show("Error: From row: " + e.RowIndex + "Col: " + e.ColumnIndex + " Message: " + e.Exception.Message);
}
Putting all this together in the forms Load
event may look something like below. That should do it. Below shows this in action.
using System.Diagnostics;
using System.Linq;
List<ExerciseAndVideo> ExerciseList;
List<Zone> ZoneList;
ComboBox CurCombo;
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
SetZoneListFromDB();
SetExerciseListFromDB();
AddColumnsToGrid();
dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter;
}
Lastly, as previously commented, this example uses a grid that is NOT bound to a data source. If you intend to use a data source for the grid that contains existing data… Then it would be wise to add two additional steps.
BEFORE the gird’s data source is set… It is highly recommended that you check each Zone and Exercise values in the data source. If there is a Zone or Exercise that is NOT is the Zone or Exercise list, then the grid will throw its DataError
when the grid’s data source is set. In addition, IF an Exercise does not belong to the given Zone, then the grid will throw its DataError
. In other words, if the Exercise on a row of data does NOT BELONG to the Zone it has, then you will need to fix this before setting the grid’s DataSource
.
Once you have checked to makes sure the Zone and Exercise data is good, then AFTER the grid’s data source is set you will need to loop through all the rows in the grid and “filter” each Exercise combo box based on the selected Zone. When the data is loaded into the grid, obviously the events we previously used are NOT fired. Fortunately you will only need to do this ONCE after the data is loaded.
I hope this makes sense and helps.
Upvotes: 4