.NET 4.x Отслеживание изменения DataGridViewComboBoxCell - C#

Узнай цену своей работы

Формулировка задачи:

Добый день. Начал изучать С# и столкнулся с одной проблеймой. Есть таблица DataViewGrid, в которую дабавляю данные из БД. В этой таблице мне нужно изменять данные. Для удобства я добавил 3 списка. Вот код добавления:
DataGridViewComboBoxCell cmb = new DataGridViewComboBoxCell();
DataGridViewComboBoxCell cmb1 = new DataGridViewComboBoxCell();
DataGridViewComboBoxCell cmb2 = new DataGridViewComboBoxCell();
 
                cmb.MaxDropDownItems = 5;
                cmb.Items.Add("Машинист");
                cmb.Items.Add("Помощник");
                cmb.Items.Add("Дублер");
                cmb.Items.Add("Машинист - инструктор");
                cmb.Items.Add("Водитель");
                dataGridView1.Rows[6].Cells[0] = cmb;
                cmb.Value = (string)dataReader["post"];

                cmb2.MaxDropDownItems = 2;
                cmb2.Items.Add("М");
                cmb2.Items.Add("Ж");
                dataGridView1.Rows[10].Cells[0] = cmb2;
                cmb2.Value = (string)dataReader["gender"];

                if (cmb.Value.ToString() == "Машинист")
                {
                    cmb1.MaxDropDownItems = 3;
                    cmb1.Items.Add("1 кл");
                    cmb1.Items.Add("2 кл");
                    cmb1.Items.Add("3 кл");
                    dataGridView1.Rows[7].Cells[0] = cmb1;
                    cmb1.Value = (string)dataReader["class"];
                }
                else
                {
                    cmb1.MaxDropDownItems = 1;
                    dataGridView1.Rows[7].Cells[0] = cmb1;
                }
Мне нужно отследить изменения в списке "cmb". Т.е. Если там выбрано "Машинист", то в списке "cmb1" нужно добавить список классов, если выбрано что-либо другое, то список очищаю. Я думал, что в DataGridViewComboBoxCell есть события, а их увы нет... Сделал по событию "CellParsing". Вот код события:
private void dataGridView1_CellParsing(object sender, DataGridViewCellParsingEventArgs e)
        {
            if (e.RowIndex == 6)
            {
                //MessageBox.Show(cmb.Selected.ToString());
                if (cmb.Value.ToString() == "Машинист")
                {
                    if (cmb1.MaxDropDownItems == 1)
                    {
                        cmb1.MaxDropDownItems = 3;
                        cmb1.Items.Add("1 кл");
                        cmb1.Items.Add("2 кл");
                        cmb1.Items.Add("3 кл");
                    }
                }
                else
                {
                    cmb1.MaxDropDownItems = 1;
                    cmb1.Value = null;
                    cmb1.Items.Clear();
                }
            }
        }
Но проблема в том, что при первом выборе элемента списка значение не заносится в cmb.Value. Нужно выбрать еще раз и тогда прошлой выбранное внесется в Value. Так же после выбора элемента нужно кликнуть на любой ячейке таблицы, что бы вызвать событие CellParsing. Подскажите как правильно сделать отслеживание изменения значений в списке, что бы не счелкать на любой ячейке и не выбирать два раза значение... То что смог придумать это сделать свой класс DataGridViewComboBoxCell с добавлением события изменения значения ячейки, но для этого моих знаний пока не хватает... Буду очнь благодарен за помощь
Вроде получилось, наверно, не совсем правильно... Но увы, пока так. Если можно по другому посоветуйте как.
 
        //определение ячейки, на которую нажали. И в зависимости от выбранной ячейки выводятся разные списки
        private void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e)
        {
            SetComboBoxCellType objChangeCellType = new SetComboBoxCellType(ChangeCellToComboBox);
            if (e.RowIndex == 6)
            {
                this.dataGridView1.BeginInvoke(objChangeCellType, e.RowIndex);
                bIsComboBox = false;
            }
            if (e.RowIndex == 7)
            {
                this.dataGridView1.BeginInvoke(objChangeCellType, e.RowIndex);
                bIsComboBox = false;
            }
            if (e.RowIndex == 10)
            {
                this.dataGridView1.BeginInvoke(objChangeCellType, e.RowIndex);
                bIsComboBox = false;
            }
        }
 
        //создание и вывод списков в зависимости от нажатой ячейки
        private void ChangeCellToComboBox(int iRowIndex)
        {
            if (iRowIndex == 6)
            {
                if (bIsComboBox == false)
                {
                    DataGridViewComboBoxCell dgComboCell = new DataGridViewComboBoxCell();
                    dgComboCell.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
 
                    DataTable dt = new DataTable();
                    dt.Columns.Add("work", typeof(string));
 
                    //for (int i = 0; i < 5; i++)
                    //{
                    //DataRow dr = dt.NewRow();
                    //dr["Name"] = "Name - " + i.ToString();
 
                    dt.Rows.Add("Машинист");
                    dt.Rows.Add("Помощник");
                    dt.Rows.Add("Машинист - инструктор");
                    dt.Rows.Add("Водитель");
                    dt.Rows.Add("Дублер");
 
                    //}
                    //for (int i = 0; i < 5; i++)
 
                    dgComboCell.DataSource = dt;
                    dgComboCell.ValueMember = "work";
                    dgComboCell.DisplayMember = "work";
 
                    try
                    {
                        MessageBox.Show(dgComboCell.Value.ToString());
                    }
                    catch
                    { }
                    dataGridView1.Rows[iRowIndex].Cells[dataGridView1.CurrentCell.ColumnIndex] = dgComboCell;
                    bIsComboBox = true;
                }
            }
            if (iRowIndex == 7)
            {
                if (bIsComboBox == false)
                {
                    DataGridViewComboBoxCell dgComboCell = new DataGridViewComboBoxCell();
                    dgComboCell.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
 
                    DataTable dt = new DataTable();
                    dt.Columns.Add("class", typeof(string));
 
                    //for (int i = 0; i < 5; i++)
                    //{
                    //DataRow dr = dt.NewRow();
                    //dr["Name"] = "Name - " + i.ToString();
 
                    dt.Rows.Add("1 кл");
                    dt.Rows.Add("2 кл");
                    dt.Rows.Add("3 кл");
 
                    //}
                    //for (int i = 0; i < 5; i++)
 
                    dgComboCell.DataSource = dt;
                    dgComboCell.ValueMember = "class";
                    dgComboCell.DisplayMember = "class";
 
                    dataGridView1.Rows[iRowIndex].Cells[dataGridView1.CurrentCell.ColumnIndex] = dgComboCell;
                    bIsComboBox = true;
                }
            }
 
            if (iRowIndex == 10)
            {
                if (bIsComboBox == false)
                {
                    DataGridViewComboBoxCell dgComboCell = new DataGridViewComboBoxCell();
                    dgComboCell.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
 
                    DataTable dt = new DataTable();
                    dt.Columns.Add("gender", typeof(string));
 
                    //for (int i = 0; i < 5; i++)
                    //{
                    //DataRow dr = dt.NewRow();
                    //dr["Name"] = "Name - " + i.ToString();
 
                    dt.Rows.Add("М");
                    dt.Rows.Add("Ж");
 
                    //}
                    //for (int i = 0; i < 5; i++)
 
                    dgComboCell.DataSource = dt;
                    dgComboCell.ValueMember = "gender";
                    dgComboCell.DisplayMember = "gender";
 
                    dataGridView1.Rows[iRowIndex].Cells[dataGridView1.CurrentCell.ColumnIndex] = dgComboCell;
                    bIsComboBox = true;
                }
            }
        }
//после завершения изменения обрабатываю событие и смотрю что было выбрано. Если выбрано "Машинист", то разрешаю изменение ячейки со списком класс, в противном случае запрещаю изменение ячейки.
 private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex == 6)
            {
                if (dataGridView1[0, 6].Value != null)
                {
                    if (dataGridView1[0, 6].Value.ToString() != "Машинист")
                    {
                        dataGridView1.Rows[7].Cells[0].ReadOnly = true;
                    }
                    else
                    {
                        dataGridView1.Rows[7].Cells[0].ReadOnly = false;
                    }
                }
            }
        }

Решение задачи: «.NET 4.x Отслеживание изменения DataGridViewComboBoxCell»

textual
Листинг программы
public delegate void valchng(object sender, EventArgs e);
    public class MyDataGridViewComboBoxCell : DataGridViewComboBoxCell
    {
        public event valchng ValueChanged;
 
        protected override bool SetValue(int rowIndex, object value)
        {
 
            if (ValueChanged != null && rowIndex!=-1)
            {
 
                base.SetValue(rowIndex, value);
                ValueChanged(this, new EventArgs());
                return true;
 
            } return base.SetValue(rowIndex, value);
 
        }
 
        protected override object GetValue(int rowIndex)
        {
            return base.GetValue(rowIndex);
        }
    }

Оцени полезность:

14   голосов , оценка 4.357 из 5
Похожие ответы