Не удается получить последний выбранный элемент в DataGridViewComboBoxCell

Моя проблема такова: у меня есть приложение C#, имеющее datagridview, в столбцах которого есть текстовые поля и выпадающие списки. Все столбцы получают данные из базы данных. Текстовые поля только для чтения. Когда я запрашиваю значения в каждой строке, я получаю значение последнего выбранного компонента (то есть значение комбинированного списка, потому что текстовые поля доступны только для чтения) как ноль.

Например:

У меня 10 клеток подряд. Комбоксы находятся в 7-м, 8-м и 9-м индексах подряд, где индексы от 0 до 6 являются текстовыми полями. Когда я выбираю 3 из них (в порядке 7, 8, 9), я не могу получить значение ячейки 9.

row.Cells[7].Value в порядке,row.Cells[8].Value в порядке, иrow.Cells[9].Value является null

Когда я выбираю любые два из них, скажем, сначала 8, а затем 7, я не могу получить значение ячейки 7.

row.Cells[8].Value в порядке иrow.Cells[7].Value является null

Когда я выбираю только один элемент, скажем, 9, я снова получаю нулевое значение ячейки.

В результате я получаю последний выбранный DataGridViewComboBoxCell как ноль.

Может кто-нибудь помочь мне в моей проблеме, пожалуйста? Спасибо за вашу помощь.

Вот мой код:

        private void cmbVariable_SelectedIndexChanged(object sender, EventArgs e)
        {
            ComboBox cmb = sender as ComboBox;
            BringQuery(cmb.SelectedItem.ToString());
        }

        private void BringQuery(string option)
        {
            SqlConnection conn = new SqlConnection("Server = 10.2.6.14; Database = TTS; uid = myuser; password = mypassword");
            DataTable dt1 = new DataTable();
            SqlCommand cmd1 = new SqlCommand("select Track_Number, Parking_Area, Mission_Number, Track_Info, Time, Direction, Explanation from Traffic_Run_Table where Op_Type=@myType", conn);
            SqlCommand cmd2 = new SqlCommand("select * from Traffic_Track_Table", conn);
            SqlCommand cmd3 = new SqlCommand("select * from Traffic_Driver order by Id_Number", conn);

            SqlDataAdapter sda1 = new SqlDataAdapter(cmd1);
            cmd1.Parameters.Add(new SqlParameter("myType", option));
            try
            {
                conn.Open();
                sda1.Fill(dt1);
                dataGridView2.AutoGenerateColumns = false;
                foreach (DataGridViewColumn col in dataGridView2.Columns)
                {
                    col.DataPropertyName = col.Name;
                }
                dataGridView2.DataSource = dt1;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            DataGridViewComboBoxColumn cmbCol1, cmbCol2, cmbCol3;

            SqlDataAdapter sda2 = new SqlDataAdapter(cmd2);
            DataTable dt2 = new DataTable();
            try
            {
                cmbCol1 = new DataGridViewComboBoxColumn();
                cmbCol1.HeaderText = "Track 1";
                cmbCol1.Name = "Track1";
                cmbCol1.DataPropertyName = cmbCol1.Name;
                cmbCol1.ValueType = typeof(int);
                cmbCol1.Width = 50;


                cmbCol2 = new DataGridViewComboBoxColumn();
                cmbCol2.HeaderText = "Track 2";
                cmbCol2.Name = "Track2";
                cmbCol2.DataPropertyName = cmbCol2.Name;
                cmbCol2.ValueType = typeof(int);
                cmbCol2.Width = 50;

                sda2.Fill(dt2);
                dt2.Columns[0].ColumnName = "Track";
                foreach (DataRow dr in dt2.Rows)
                {
                    cmbCol1.Items.Add(Convert.ToInt32(dr["Track"]));
                    cmbCol2.Items.Add(Convert.ToInt32(dr["Track"]));
                }
                dataGridView2.Columns.Add(cmbCol1);
                dataGridView2.Columns.Add(cmbCol2);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            SqlDataAdapter sda3 = new SqlDataAdapter(cmd3);
            DataTable dt3 = new DataTable();
            try
            {
                cmbCol3 = new DataGridViewComboBoxColumn();
                cmbCol3.HeaderText = "Driver";
                cmbCol3.Name = "Driver";
                cmbCol3.DataPropertyName = cmbCol3.Name;
                cmbCol3.ValueType = typeof(string);
                cmbCol3.Width = 260;

                sda3.Fill(dt3);
                dt3.Columns[0].ColumnName = "Id";
                dt3.Columns[1].ColumnName = "Driver";
                dt3.Columns[2].ColumnName = "Mission";
                foreach (DataRow dr in dt3.Rows)
                {
                    cmbCol3.Items.Add(Convert.ToString(dr["Id"]).Trim() + " - " + Convert.ToString(dr["Dirver"]).Trim() + " - " + Convert.ToString(dr["Mission"]).Trim());
                }
                dataGridView2.Columns.Add(cmbCol3);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            conn.Close();
        }

        public string CheckNull(object value, Type objType)
        {
            string retVal = string.Empty;

            if (value == null || value.ToString() == " " || value.ToString() == "")
            {
                if (objType == typeof(int))
                {
                    retVal = "0";
                }
                if (objType == typeof(string))
                {
                    retVal = "-";
                }
            }
            else
            {
                retVal = value.ToString();
            }
            return retVal;
        }

        private void Save_Click(object sender, EventArgs e)
        {
            SqlConnection connForSave = new SqlConnection("Server = 10.2.6.14; Database = TTS; uid = myuser; password = mypassword");
            SqlCommand cmdForSave = new SqlCommand("insert into Traffic_Records values (@type, @trackNumber, @parkingArea, @missionNmb, @trackInfo, @time, @direction, @explanation, @track1, @track2, @driverId, @driverName, @driverMission, @date)", connForSave);
            foreach (DataGridViewRow row in dataGridView2.Rows)
            {
                try
                {
                    dataGridView2[7, row.Index].Selected = false;
                    dataGridView2[8, row.Index].Selected = false;
                    dataGridView2[9, row.Index].Selected = false;

                    connForSave.Open();
                    cmdForSave.Parameters.AddWithValue("type", CheckNull(cmbVairable.SelectedItem.ToString(), typeof(string)));
                    cmdForSave.Parameters.AddWithValue("trackNumber", Convert.ToInt16(CheckNull(row.Cells[0].Value, typeof(int))));
                    cmdForSave.Parameters.AddWithValue("parkingArea", CheckNull(row.Cells[1].Value, typeof(string)));
                    cmdForSave.Parameters.AddWithValue("missionNmb", Convert.ToInt16(CheckNull(row.Cells[2].Value, typeof(int))));
                    cmdForSave.Parameters.AddWithValue("trackInfo", CheckNull(row.Cells[3].Value, typeof(string)));
                    cmdForSave.Parameters.AddWithValue("time", CheckNull(row.Cells[4].Value, typeof(string)));
                    cmdForSave.Parameters.AddWithValue("direction", CheckNull(row.Cells[5].Value, typeof(string)));
                    cmdForSave.Parameters.AddWithValue("explanation", CheckNull(row.Cells[6].Value, typeof(string)));
                    cmdForSave.Parameters.AddWithValue("track1", Convert.ToInt16(CheckNull(row.Cells[7].Value, typeof(int))));
                    cmdForSave.Parameters.AddWithValue("track2", Convert.ToInt16(CheckNull(row.Cells[8].Value, typeof(int))));

                    string[] sArray = null;

                    if (string.Compare(CheckNull(row.Cells[9].Value, typeof(string)), "0") != 0 && string.Compare(CheckNull(row.Cells[9].Value, typeof(string)), "-") != 0)
                    {
                        sArray = row.Cells[9].Value.ToString().Split('-');
                        sArray[0] = sArray[0].Remove(sArray[0].Length - 2, 1);
                        sArray[1] = sArray[1].Remove(0, 1);
                        sArray[1] = sArray[1].Remove(sArray[1].Length - 2, 1);
                        sArray[2] = sArray[2].Remove(0, 1);
                    }
                    else
                    {
                        string temp = "0 - -";
                        sArray = temp.Split(' ');
                    }

                    cmdForSave.Parameters.AddWithValue("driverId", Convert.ToInt16(sArray[0]));
                    cmdForSave.Parameters.AddWithValue("driverName", sArray[1]);
                    cmdForSave.Parameters.AddWithValue("driverMission", sArray[2]);
                    cmdForSave.Parameters.AddWithValue("date", DateTime.Now);

                    cmdForSave.ExecuteNonQuery();

                    cmdForSave.Parameters.Clear();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message + "\n Line Number: " + ex.LineNumber());
                }
                connForSave.Close();
            } 
        }

1 ответ

Решение

Это происходит потому, что DataGridView не фиксирует внесенные пользователем изменения мгновенно, но только после проверки строки (думаю, здесь может быть нет). Поэтому после того, как вы выбрали последнее значение и не изменили строку (так что событие validate не сработало), значение в комбинированном окне все еще равно нулю.

Чтобы исправить это добавить CurrentCellDirtyStateChanged (подробнее здесь MSDN событие к вашей сетке:

private void GridCurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    dgvAssignedProperties.CommitEdit(DataGridViewDataErrorContexts.Commit);
}

и именно поэтому новые ценности совершаются сразу.

Другие вопросы по тегам