通过在单元格中键入将项目动态添加到DataGridView ComboBox列 [英] Dynamically add item to DataGridView ComboBox Column by typing in the cell
问题描述
我有一个 DataGridView
,其中有一个 ComboBox
列,当下拉列表时,我必须更新每个ComboBox的可能值节目。我还必须使 ComboBox
es能够具有自定义类型的值。键入新值时,应将其添加到可能值列表中。问题是我得到无限多个 DataError
事件触发器(错误消息框),我知道如何通过仅更改 DataGridViewDataErrorEventArgs中的字段来处理它
对象,但我知道这不是正确的处理方式:
I have a DataGridView
that has a ComboBox
column and I must update each ComboBox's possible values when its drop down shows. I also must make the ComboBox
es capable of having custom typed values. When a new value is typed, it should be added to the list of possible values. The problem is that I get infinitely many DataError
event triggers (error message boxes), I know how to handle it by just changing a field in the DataGridViewDataErrorEventArgs
object, but I know it is not the correct way to handle it:
private void DataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
e.Cancel = false;
}
如果我以错误的方式操作,请从下拉列表中选择一个值向下或输入新值时,会触发 CellValueChanged
,但关闭的 ComboBox
不会显示当前值,但已经显示现有值(列表中的第一个)。
If I do it in the incorrect way, after selecting a value from the drop down or typing a new value, the CellValueChanged
is triggered but the closed ComboBox
does not display the current value but an already existing value (the first in the list).
在以下代码中,Form子类为 Form2
,值存储在 str
字段中,并调用 UpdatePossibleValues
方法来更新所有<$ c中的可能值$ c> ComboBox 位于数据网格视图的唯一列中,即 DataGridViewComboBoxColumn
:
In the following code the Form subclass is Form2
, the initial values are stored in the str
field and the UpdatePossibleValues
method is called to update the possible values in all the ComboBox
es inside the only column in the data grid view, 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);
}
}
}
截屏:
推荐答案
要将项目动态添加到 DataGridViewComboBoxColumn
:
- Hanlde
EditingControlShowing
并获得DataGridViewComboBoxEditingControl
- 将编辑控件
DropDownStyle
设置为DropDown
- 句柄
正在验证
编辑控件事件,并确保仅将事件处理程序附加一次。 - 检查
文本是否
的编辑控件在以下项目中不存在:
- 将其添加到th的数据源e列
- 然后通过将列的数据源设置为null并再次分配数据源来重置该列的数据源。
- Hanlde
EditingControlShowing
and get theDataGridViewComboBoxEditingControl
- Set editing control
DropDownStyle
toDropDown
- Handle
Validating
event of editing control and make sure you attach the event handler just once. - Check if the
Text
of the editing control doesn't exists in the items:- Add it to data source of the column
- Then reset data source of the column by setting it to null and assigning data source again.
注意:
-
如果您有多个组合框,确保对组合框使用不同的数据源,并在验证事件中更新相应的数据源。
If you have multiple combo box, make sure you use different data sources for combo boxes and update corresponding data source in validating event.
如果使用匿名方法处理事件,请确保关于捕获变量的正确假设。为简单起见,您可以使用常规方法处理事件。
If you handle the events using anonymous method, make sure you have a correct assumption about captured variables. To make it simple, you can handle the event using a normal method.
示例
下面的示例显示 DataGridView
具有两个 DataGridViewComboBoxColumn
对于第二个示例,可以在运行时在组合框中键入新值。
The following example shows a DataGridView
having two DataGridViewComboBoxColumn
which for the second one, you can add new values by typing in the combo box at run-time.
要运行该示例,请创建一个窗体
并将 DataGridView
放到新窗体上,然后将以下代码复制并粘贴到该窗体中:
To run the example, create a Form
and drop a DataGridView
on a new Form and just copy and paste the following code in the form:
private List<String> comboSource1;
private List<String> comboSource2;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
comboSource1 = new List<string> { "A", "B" };
comboSource2 = new List<string> { "1", "2" };
var dt = new DataTable();
dt.Columns.Add("C1");
dt.Columns.Add("C2");
dt.Rows.Add("A", "1");
dt.Rows.Add("B", "2");
var c1 = new DataGridViewComboBoxColumn();
c1.Name = "C1";
c1.DataPropertyName = "C1";
c1.DataSource = comboSource1;
var c2 = new DataGridViewComboBoxColumn();
c2.Name = "C2";
c2.DataPropertyName = "C2";
c2.DataSource = comboSource2;
dataGridView1.Columns.AddRange(c1, c2);
this.dataGridView1.DataSource = dt;
dataGridView1.EditingControlShowing += dataGridView1_EditingControlShowing;
dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter;
}
private void dataGridView1_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
var dataGridView = sender as DataGridView;
if (dataGridView?.CurrentCell?.ColumnIndex != 1) return;
var comboBox = e.Control as DataGridViewComboBoxEditingControl;
if (comboBox == null) return;
comboBox.DropDownStyle = ComboBoxStyle.DropDown;
if (!true.Equals(comboBox.Tag))
{
comboBox.Tag = true;
comboBox.Validating += (obj, args) =>
{
var column = (DataGridViewComboBoxColumn)dataGridView.CurrentCell.OwningColumn;
var list = comboBox.DataSource as List<string>;
if (list == null) return;
var txt = comboBox.Text;
if (!list.Contains(txt))
{
list.Add(txt);
column.DataSource = null;
column.DataSource = list;
}
dataGridView.CurrentCell.Value = txt;
dataGridView.NotifyCurrentCellDirty(true);
};
}
}
这篇关于通过在单元格中键入将项目动态添加到DataGridView ComboBox列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!