自学 C# DataGridView Combobox?
A self-learning C# DataGridView Combobox?
我想在DataGridView中有一列ComboBoxes,它允许用户自由输入一些文本,这些文本收集在下拉菜单中,这样在下一个框中输入相同的文本会更快。我宁愿不使用 DataGridViewComboBoxColumn,除非我真的必须这样做。
以下代码几乎可以完成工作,但存在以下问题:
输入一些新文本并点击return后,新输入的文本立即被旧值替换
但是新文本已成功添加到所有组合框的下拉菜单中
当我 select 在其中一个框中添加这个新添加的文本时,我收到 DataGridView-Exceptions 抱怨无效值。
似乎这些框以某种方式具有用于验证目的的数据源副本,但未更新?
public partial class Form1 : Form
{
List<string> data = new List<string>(); // shared data source for all ComboBoxes
private void checkData(string s) // check wether s in the list, add it if not, keep things sorted
{
if (data.Contains(s))
return;
data.Add(s);
data.Sort();
}
private void addCell(string s) // add a new cell to the grid
{
checkData(s);
DataGridViewComboBoxCell c = new DataGridViewComboBoxCell();
c.DataSource = data;
c.Value = s;
int i = theGrid.Rows.Add();
theGrid.Rows[i].Cells[0] = c;
}
public Form1()
{
InitializeComponent();
theGrid.ColumnCount = 1;
addCell("Foo");
addCell("Bar");
}
// handler to enable the user to enter free text
private void theGrid_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
ComboBox cb = e.Control as ComboBox;
if (cb != null)
cb.DropDownStyle = ComboBoxStyle.DropDown;
}
// handler which adds the entered text to the data source
private void theGrid_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
if (e.RowIndex < 0 || e.ColumnIndex < 0)
return;
checkData(e.FormattedValue.ToString());
}
}
经过一些测试,我猜测各个组合框并没有像您想象的那样得到更新。似乎在 checkData
方法中,data
被更新为新的 s
。这将在视觉上更新组合框单元格,但是需要更新每个组合的 DataSource
。因此,选择新的添加值时DataError
异常。
考虑到每个组合框单元格都是“独立的”,而不是 DataGridViewComboBoxColumn
的一部分……然后需要遍历所有行来更新每个组合框单元格。我不确定为什么这里不使用 DataGridViewComboBoxColumn
。
private void checkData(string s) // check wether s in the list, add it if not, keep things sorted
{
if (data.Contains(s))
return;
data.Add(s);
data.Sort();
// now because each cell is independent... we have to update each data source!
UpdateCombos();
}
private void UpdateCombos() {
foreach (DataGridViewRow row in theGrid.Rows) {
if ((!row.IsNewRow) && (row.Cells[0].Value != null)) {
string currentValue = row.Cells[0].Value.ToString();
DataGridViewComboBoxCell c = new DataGridViewComboBoxCell();
c.Value = currentValue;
c.DataSource = data;
row.Cells[0] = c;
}
}
}
使用发布的代码,将对 UpdateCombos
的调用添加到 checkData
方法中。此方法按预期循环遍历网格中的所有行,并用更新的数据替换每个组合框。我不会不同意替换数据源可能是明智的,但是我会使用组合框列,下面的代码就是这样做的。通过此更改,不需要 UpdateCombos
,只需更新组合框列即可。
数据源更新频繁,DataGridViewComboBoxColumn
暴露
private List<string> comboData;
private DataGridViewComboBoxColumn comboColumn;
private void Form2_Load(object sender, EventArgs e) {
comboData = new List<string>();
comboData.Add("Foo");
comboData.Add("Bar");
comboColumn = new DataGridViewComboBoxColumn();
comboColumn.DataSource = comboData;
theGrid2.Columns.Add(comboColumn);
theGrid2.RowCount = 3;
}
private void checkData2(string s) {
if (!comboData.Contains(s)) {
comboData.Add(s);
comboData.Sort();
comboColumn.DataSource = null;
comboColumn.DataSource = comboData;
}
}
希望对您有所帮助
我想在DataGridView中有一列ComboBoxes,它允许用户自由输入一些文本,这些文本收集在下拉菜单中,这样在下一个框中输入相同的文本会更快。我宁愿不使用 DataGridViewComboBoxColumn,除非我真的必须这样做。
以下代码几乎可以完成工作,但存在以下问题:
输入一些新文本并点击return后,新输入的文本立即被旧值替换
但是新文本已成功添加到所有组合框的下拉菜单中
当我 select 在其中一个框中添加这个新添加的文本时,我收到 DataGridView-Exceptions 抱怨无效值。
似乎这些框以某种方式具有用于验证目的的数据源副本,但未更新?
public partial class Form1 : Form
{
List<string> data = new List<string>(); // shared data source for all ComboBoxes
private void checkData(string s) // check wether s in the list, add it if not, keep things sorted
{
if (data.Contains(s))
return;
data.Add(s);
data.Sort();
}
private void addCell(string s) // add a new cell to the grid
{
checkData(s);
DataGridViewComboBoxCell c = new DataGridViewComboBoxCell();
c.DataSource = data;
c.Value = s;
int i = theGrid.Rows.Add();
theGrid.Rows[i].Cells[0] = c;
}
public Form1()
{
InitializeComponent();
theGrid.ColumnCount = 1;
addCell("Foo");
addCell("Bar");
}
// handler to enable the user to enter free text
private void theGrid_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
ComboBox cb = e.Control as ComboBox;
if (cb != null)
cb.DropDownStyle = ComboBoxStyle.DropDown;
}
// handler which adds the entered text to the data source
private void theGrid_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
if (e.RowIndex < 0 || e.ColumnIndex < 0)
return;
checkData(e.FormattedValue.ToString());
}
}
经过一些测试,我猜测各个组合框并没有像您想象的那样得到更新。似乎在 checkData
方法中,data
被更新为新的 s
。这将在视觉上更新组合框单元格,但是需要更新每个组合的 DataSource
。因此,选择新的添加值时DataError
异常。
考虑到每个组合框单元格都是“独立的”,而不是 DataGridViewComboBoxColumn
的一部分……然后需要遍历所有行来更新每个组合框单元格。我不确定为什么这里不使用 DataGridViewComboBoxColumn
。
private void checkData(string s) // check wether s in the list, add it if not, keep things sorted
{
if (data.Contains(s))
return;
data.Add(s);
data.Sort();
// now because each cell is independent... we have to update each data source!
UpdateCombos();
}
private void UpdateCombos() {
foreach (DataGridViewRow row in theGrid.Rows) {
if ((!row.IsNewRow) && (row.Cells[0].Value != null)) {
string currentValue = row.Cells[0].Value.ToString();
DataGridViewComboBoxCell c = new DataGridViewComboBoxCell();
c.Value = currentValue;
c.DataSource = data;
row.Cells[0] = c;
}
}
}
使用发布的代码,将对 UpdateCombos
的调用添加到 checkData
方法中。此方法按预期循环遍历网格中的所有行,并用更新的数据替换每个组合框。我不会不同意替换数据源可能是明智的,但是我会使用组合框列,下面的代码就是这样做的。通过此更改,不需要 UpdateCombos
,只需更新组合框列即可。
数据源更新频繁,DataGridViewComboBoxColumn
暴露
private List<string> comboData;
private DataGridViewComboBoxColumn comboColumn;
private void Form2_Load(object sender, EventArgs e) {
comboData = new List<string>();
comboData.Add("Foo");
comboData.Add("Bar");
comboColumn = new DataGridViewComboBoxColumn();
comboColumn.DataSource = comboData;
theGrid2.Columns.Add(comboColumn);
theGrid2.RowCount = 3;
}
private void checkData2(string s) {
if (!comboData.Contains(s)) {
comboData.Add(s);
comboData.Sort();
comboColumn.DataSource = null;
comboColumn.DataSource = comboData;
}
}
希望对您有所帮助