В заметке рассказано как получить индекс выпадающего списка находящегося в ячейке DataGridView, иначе говоря, показано как получить SelectedIndex находящегося в ячейке ComboBox-а. Как добавить в DataGridView колонку с выпадающими списками или с чекбоксами можете посмотреть в одной из прошлых статей.
Проблема заключается в том, что получив объект, находящийся в ячейке, мы не можем получить его индекс как с обычным ComboBox-ом, т.е., например, такой код не будет работать:
DataGridViewComboBoxCell cmb = dataGridView1.CurrentCell as DataGridViewComboBoxCell; int i = cmb.SelectedIndex;
Всё потому, что у DataGridViewComboBoxCell нет свойства SelectedIndex. Для решения проблемы я взял за основу информацию из ответа на вопрос на Stack Overflow. Там описано 2 способа как получить индекс выбранного элемента. Первый способ навел меня на размышления и я его реализовал по-своему.
1-й способ. Использование EditingControlShowing
Суть идеи в том, чтобы использовать событие EditingControlShowing, которое происходит когда ячейка переходит в состояние редактирования и отображается контрол, находящийся в этой ячейке. Во время этого события я на этот контрол (ComboBox) навешиваю событие изменения выбранного элемента.
Предположим, что у нас в DataGridView вторая колонка содержит ComboBox-ы:
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) { if (dataGridView1.CurrentCell.ColumnIndex == 1) { ComboBox combo = e.Control as ComboBox; combo.SelectedIndexChanged -= new EventHandler(Control_Changed); combo.SelectedIndexChanged += new EventHandler(Control_Changed); } }
Как видно в коде, я сначала "снимаю" с ComboBox-а событие, а потом заново его "навешиваю". Это сделано специально, чтобы не происходило повторных "навешиваний". Пользователь ведь может зайти в ячейку, поменять значение выпадающего списка, потом уйти в другую ячейку, а затем снова вернуться и опять поменять значение списка. Так вот, чтобы каждый раз, когда он редактирует ComboBox не происходило многократного назначения события, я и делаю сначала его удаление.
Теперь обработчик события изменения ComboBox-а:
private void Control_Changed(object sender, System.EventArgs e) { int col = dataGridView1.CurrentCell.ColumnIndex; if (col == 1) { int i = ((ComboBox)sender).SelectedIndex; dataGridView1.CurrentRow.Cells[col - 1].Tag = i.ToString(); } }
Таким образом, при изменении выбранного элемента в ComboBox-е его индекс запишется в свойство Tag ячейки в которой находится этот ComboBox. Можно так же сохранить выбранный индекс и в массив или куда пожелаете, а потом, когда понадобится индекс, его будет легко получить.
2-й способ. Поиск по значению.
Этот метод очень прост, но имеет недостаток. Его смысл в том, что нужно сначала получить контрол в ячейке и потом в нем найти индекс выбранного значения.
DataGridViewComboBoxCell cmb = (DataGridViewComboBoxCell)dataGridView1.CurrentCell; int i = cmb.Items.IndexOf(cmb.Value);
Минус у этого способа, как я думаю, лишь один: если в выпадающем списке будут повторяющиеся названия элементов, то будет определяться индекс первого найденного, в то время как на самом деле выбран другой с таким же названием. Каким способом пользоваться, решайте сами, в зависимости от ситуации и потребности.
Комментарии к статье:
Добавить комментарий: