У меня есть DataGridView
, в котором есть столбец ComboBox
, и я должен обновить возможные значения каждого ComboBox, когда появится его раскрывающийся список. Я также должен сделать ComboBox
es способными иметь пользовательские значения. Когда вводится новое значение, оно должно быть добавлено в список возможных значений. Проблема в том, что я получаю бесконечно много DataError
событийных триггеров (ящиков с сообщениями об ошибках), я знаю, как справиться с этим, просто изменив поле в DataGridViewDataErrorEventArgs
объекте, но я знаю, что это неправильный способ обработки:
private void DataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
e.Cancel = false;
}
Если я делаю это неправильно, после выбора значения из выпадающего списка или ввода нового значения, CellValueChanged
срабатывает, но закрытое ComboBox
отображает не текущее значение, а уже существующее значение ( первый в списке).
В следующем коде подкласс Form равен Form2
, начальные значения сохраняются в поле str
, и вызывается метод UpdatePossibleValues
для обновления возможных значений во всех ComboBox
внутри единственного столбца. в представлении таблицы данных a DataGridViewComboBoxColumn
:
public Form2()
{
InitializeComponent();
dataGridView1.EditingControlShowing += DataGridView1_EditingControlShowing;
UpdatePossibleValues();
}
internal List<string> str = new List<string>()
{
"val1",
"val2"
};
private void DataGridView1_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
if (dataGridView1.CurrentCell == null ||
dataGridView1.CurrentCell.OwningColumn == null ||
dataGridView1.CurrentCell.OwningColumn.Name != "column1")
{
return;
}
var combo = e.Control as DataGridViewComboBoxEditingControl;
if (combo == null)
{
return;
}
var cb = combo as ComboBox;
UpdatePossibleValues(cb);
cb.DropDownStyle = ComboBoxStyle.DropDown; // this makes the ComboBoxes editable
cb.Validating += Cb_Validating;
}
private void Cb_Validating(object sender, System.ComponentModel.CancelEventArgs e)
{
var cbo = sender as ComboBox;
string t = cbo.Text;
var cell = (DataGridViewComboBoxCell)dataGridView1.CurrentCell;
// add the value to the list if it is not there
if (!string.IsNullOrEmpty(t) &&
!cbo.Items.Contains(t))
{
str.Add(t);
UpdatePossibleValues(cbo);
cell.Value = t;
e.Cancel = false;
}
}
private void UpdatePossibleValues(ComboBox cb = null)
{
if (cb == null)
{
var col = dataGridView1.Columns[0] as DataGridViewComboBoxColumn;
col.Items.Clear();
foreach (string s in str)
{
col.Items.Add(s);
}
}
else
{
cb.Items.Clear();
foreach (string s in str)
{
cb.Items.Add(s);
}
}
}
Скриншоты: