We help IT Professionals succeed at work.

C# Winforms DataGridView ComboBox population problem.

Jeff Heilman
Jeff Heilman asked
on
Hello!

I'm trying to populate a combobox inside of a datagridview based on what shift is selected in the Operators Filter combobox.  I've been successful in populating the top combo in the datagridview but no data is showing in the rest of the rows.

There are 4 shifts, A,B,C and D which all have operators assigned.  However on any given day an operator that normally works C shift may come in to cover for someone on A.  When I bound the combobox directly to the OperatorsBindingSource every time I would filter by selecting another shift the values already selected in the dgv would disappear because the name did not exist in the filtered binding source.  As a workaround I'm trying to handle it this way.

Here is an image of the form:
ComboIssue.jpg
Here is the code I have so far that is only populating the top combo in the dgv:
private void GetOperators()
        {
            string opshift = cboOperatorFilter.SelectedItem.ToString();

            DataTable opNames = new DataTable();

            var filteredOps = from row in trackingDataSet.Operators.AsEnumerable()
                              where row.Field<string>("HomeShift") == opshift
                              select row.OperatorName.ToString();

            opNames.Columns.Add("OperatorName", typeof(string));
            foreach(string str in filteredOps)
            {
                DataRow row = opNames.NewRow();
                row["OperatorName"] = str;
                opNames.Rows.Add(row);
            }

            DataGridViewComboBoxCell comboCell = (DataGridViewComboBoxCell)dataGridView1[1, 0];
            comboCell.DataSource = null;
            comboCell.Items.Clear();
            comboCell.DataSource = opNames;
            comboCell.DisplayMember = "OperatorName";
            comboCell.ValueMember = "OperatorName";
        }

//////////****** GetOperators() is triggered by this code when the Operator Filter combo is changed:

private void cboOperatorFilter_SelectedIndexChanged(object sender, EventArgs e)
        {
            string shift = cboOperatorFilter.SelectedItem.ToString();
            GetOperators();
            //operatorsBindingSource.Filter = "[HomeShift] ='" + shift + "'";
        }

Open in new window


Any help would be greatly appreciated.  Have a great day and thank you in advance!
Jeff
Comment
Watch Question

Freelance IT Consultant
CERTIFIED EXPERT
Commented:
Seem that you only applied changes to the first row:
DataGridViewComboBoxCell comboCell = (DataGridViewComboBoxCell)dataGridView1[1, 0];

Open in new window


Going that path, you will have to update for all rows, which might not be efficient.

Maybe you should only populate combox data when user clicks on that cell (on-demand)
Jeff HeilmanBusiness Systems Mgr

Author

Commented:
Thanks, Duy.  I'm pretty new to C#, could you please give me a bit of an example please?  How would I tell GetOperators() which row to update?
Jeff HeilmanBusiness Systems Mgr

Author

Commented:
I believe I have it figured out thanks to Duy's suggestion.  I added this code to pick up the row index number and passed it to the GetOperators() method.
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == operatorDataGridViewComboBoxColumn.Index)
            {
                if (dataGridView1.SelectedCells.Count > 0)
                {
                    int i = dataGridView1.SelectedCells[0].RowIndex;
                    GetOperators(i);
                }
            }
        }

Open in new window


And here is the modified GetOperators():
 private void GetOperators(int i)
        {
            if (i > 0)
            {
                string opshift = cboOperatorFilter.SelectedItem.ToString();

                DataTable opNames = new DataTable();

                var filteredOps = from row in trackingDataSet.Operators.AsEnumerable()
                                  where row.Field<string>("HomeShift") == opshift
                                  select row.OperatorName.ToString();

                opNames.Columns.Add("OperatorName", typeof(string));
                foreach (string str in filteredOps)
                {
                    DataRow row = opNames.NewRow();
                    row["OperatorName"] = str;
                    opNames.Rows.Add(row);
                }

                DataGridViewComboBoxCell comboCell = (DataGridViewComboBoxCell)dataGridView1[1, i];
                comboCell.DataSource = null;
                comboCell.Items.Clear();
                comboCell.DataSource = opNames;
                comboCell.DisplayMember = "OperatorName";
                comboCell.ValueMember = "OperatorName";
            }
        }

Open in new window

Duy PhamFreelance IT Consultant
CERTIFIED EXPERT

Commented:
@Jeff
Super :).

Explore More ContentExplore courses, solutions, and other research materials related to this topic.