Как переключаться между DataGridViewTextBoxCell и DataGridViewComboBoxCell?

Я хочу иметь DataGridView с двумя столбцами. Первый столбец всегда будет иметь тип DataGridViewComboBoxColumn. На основе выбора в этом столбце я хотел бы иметь возможность изменить соответствующую ячейку во втором столбце либо на DataGridViewComboBoxCell, либо на DataGridViewTextBoxCell.

Я думаю, мне просто нужно сделать второй столбец типа DataGridViewColumn, но я не понимаю механику изменения типа ячейки на лету.

Я работаю с VB.NET в Visual Studio 2005.

Заранее спасибо!

Обновление: Один из способов обойти это, я полагаю, состоит в том, чтобы сделать второй столбец DataGridViewComboBoxColumn и изменить атрибуты ячейки так, чтобы он вел себя либо как раскрывающийся список, либо как ( редактируемый) раскрывающийся список без элементов. Последнее выглядит достаточно похоже на текстовое поле, с которым я мог бы жить, и это не потребовало бы изменения типа ячейки.




Ответы (2)


У меня нет версии VB.Net, но, надеюсь, этот краткий фрагмент C# поможет вам или укажет правильное направление.

В этом примере я настроил простой DataGridView с двумя столбцами. Первым из них является DataGridViewComboBox, заполненный двумя вариантами: «Текст» или «Комбо».

Второй столбец изначально установлен в DataGridViewTextBoxColumn в конструкторе.

Я обрабатываю событие CurrentCellDirtyStateChanged в DataGridView. Я проверяю, не загрязнена ли ячейка, и проверяю только первый столбец (ComboBox). Вы должны вызвать CommitEdit, чтобы получить новое значение в комбо, иначе вы будете смотреть на предыдущее значение. На основе выбора в поле со списком я затем перезаписываю ячейку во 2-м столбце новой ячейкой этого типа.

Вы бы добавили свою собственную логику (заполните раскрывающиеся списки и обработайте значение). Возможно, вы захотите сохранить значение, а затем поместить его обратно в ячейку или что-то еще.

Вот код, который я использовал и провел быстрый и грязный тест:

private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
    {
        if (dataGridView1.IsCurrentCellDirty == false)
        {
            return;
        }

        dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);

        if (dataGridView1.CurrentCell.ColumnIndex == 0)
        {               
            if (((string)dataGridView1.CurrentCell.Value) == "Text")
            {
                dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[1] = new DataGridViewTextBoxCell();
            }
            else if (((string)dataGridView1.CurrentCell.Value) == "Combo")
            {
                dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[1] = new DataGridViewComboBoxCell();
            }
        }
    }

Вот быстрый перевод VB, который я протестировал и работает.

Public Class Form1

Private Sub DataGridView1_CurrentCellDirtyStateChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DataGridView1.CurrentCellDirtyStateChanged

    If DataGridView1.IsCurrentCellDirty = False Then
        Return
    End If

    DataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)

    If DataGridView1.CurrentCell.ColumnIndex = 0 Then

        If CStr(DataGridView1.CurrentCell.Value) = "Text" Then
            DataGridView1.Rows(DataGridView1.CurrentCell.RowIndex).Cells(1) = New DataGridViewTextBoxCell

        ElseIf CStr(DataGridView1.CurrentCell.Value) = "Combo" Then
            DataGridView1.Rows(DataGridView1.CurrentCell.RowIndex).Cells(1) = New DataGridViewComboBoxCell
        End If

    End If


End Sub

Конец класса

Вы потеряете любое значение, хранящееся в этом столбце, поэтому вам нужно сначала сохранить его.

Джон

person Jon Comtois    schedule 22.11.2009
comment
Спасибо. Это полезно. На самом деле я не эксперт по VB или .NET, поэтому я вижу, что вы делаете в принципе, но мне еще предстоит выяснить механизм выделения нового DataGridViewTextBoxCell или нового DataGridViewComboBoxCell в VB. В любом случае я ценю время, которое вы потратили на свой ответ, и я попробую сегодня днем. - person John; 23.11.2009

Вы можете создать собственный шаблон ячейки, в котором размещается пользовательский элемент управления. В пользовательском элементе управления вы добавляете текстовое поле и поле со списком, а также добавляете метод/свойство, чтобы показать одно и скрыть другое.

В этом примере создается ячейка переключателя, она нетрудно изменить код для размещения пользовательского элемента управления.

person Sheng Jiang 蒋晟    schedule 23.11.2009