首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >一个自学习的C# DataGridView组合框?

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

Stack Overflow用户
提问于 2018-07-31 13:26:35
回答 1查看 131关注 0票数 0

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

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

  • 输入新文本并按回车后,新输入的文本将立即替换为旧值。
  • 但是,新文本成功地添加到所有组合框的下拉菜单中。
  • 当我在其中一个框中选择这个新添加的文本时,我会得到DataGridView--抱怨无效值的异常。

似乎为了验证起见,这些方框似乎有一个数据源的副本,而该数据源没有被更新?

代码语言:javascript
复制
    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());
        }
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-01 03:09:20

经过一些测试后,我猜想单个组合框并没有像您想象的那样得到更新。在checkData方法中,data似乎是用新的s更新的。这将可视化地更新组合框单元格,但是每个组合体的DataSource都需要更新。因此,当选择新的附加值时,将出现DataError异常。

考虑到每个组合框单元格是“独立的”而不是DataGridViewComboBoxColumn…的一部分。然后,需要循环遍历所有行,以更新每个组合框单元格。我不知道为什么这里不使用DataGridViewComboBoxColumn

代码语言:javascript
复制
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是公开的,因为数据源经常更新。

代码语言:javascript
复制
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;
  }
}

希望这有帮助

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51614526

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档