自学 C# DataGridView Combobox?

A self-learning C# DataGridView Combobox?

我想在DataGridView中有一列ComboBoxes,它允许用户自由输入一些文本,这些文本收集在下拉菜单中,这样在下一个框中输入相同的文本会更快。我宁愿不使用 DataGridViewComboBoxColumn,除非我真的必须这样做。

以下代码几乎可以完成工作,但存在以下问题:

似乎这些框以某种方式具有用于验证目的的数据源副本,但未更新?

    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;
  }
}

希望对您有所帮助