一个自学的C#DataGridView组合框?

时间:2018-07-31 13:26:35

标签: c# datagridview datagridviewcomboboxcell

我想在DataGridView中有一列ComboBoxes,它允许用户自由输入一些文本,这些文本收集在下拉菜单中,以便在下一个框中输入相同的文本更快。除非确实需要,否则我不希望使用DataGridViewComboBoxColumn。

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

  • 输入一些新文本并按回车键后,新输入的文本将立即替换为旧值

  • 但是新文本已成功添加到所有组合框的下拉菜单中

  • 当我在其中一个框中选择此新添加的文本时,我收到抱怨无效值的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());
        }
    }

1 个答案:

答案 0 :(得分:1)

经过一些测试,我猜想单个组合框没有像您认为的那样得到更新。似乎在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;
  }
}

希望有帮助