通过在单元格中键入内容将项目动态添加到 DataGridView ComboBox 列

2023-12-29

我有一个DataGridView有一个ComboBox列,我必须在其下拉列表显示时更新每个组合框的可能值。我还必须使ComboBoxes 能够具有自定义类型的值。当输入新值时,应将其添加到可能值列表中。问题是我得到了无穷多个DataError事件触发器(错误消息框),我知道如何通过更改中的字段来处理它DataGridViewDataErrorEventArgs对象,但我知道这不是处理它的正确方法:

private void DataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
    e.Cancel = false;
}

如果我以不正确的方式执行此操作,则从下拉列表中选择一个值或输入一个新值后,CellValueChanged被触发但关闭ComboBox不显示当前值,而是显示已存在的值(列表中的第一个值)。

在下面的代码中,Form子类是Form2,初始值存储在str场和UpdatePossibleValues调用方法来更新所有可能的值ComboBoxes 在数据网格视图中唯一的列内,aDataGridViewComboBoxColumn:

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:

  1. Hanlde EditingControlShowing并得到DataGridViewComboBoxEditingControl
  2. 设置编辑控制DropDownStyle to DropDown
  3. Handle Validating编辑控件的事件,并确保仅附加事件处理程序一次。
  4. Check if the Text of the editing control doesn't exists in the items:
    • 将其添加到列的数据源中
    • 然后通过将其设置为空并再次分配数据源来重置该列的数据源。

Notes:

  • 如果您有多个组合框,请确保组合框使用不同的数据源,并在验证事件中更新相应的数据源。

  • 如果您使用匿名方法处理事件,请确保您对捕获的变量有正确的假设。为了简单起见,您可以使用普通方法处理该事件。

Example

以下示例显示了一个DataGridView有两个DataGridViewComboBoxColumn对于第二个,您可以通过在运行时在组合框中键入来添加新值。

要运行该示例,请创建一个Form并放下一个DataGridView在新表单上,只需将以下代码复制并粘贴到表单中:

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);
        };
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过在单元格中键入内容将项目动态添加到 DataGridView ComboBox 列 的相关文章

随机推荐

  • onclick 事件不适用于选项

    以下是我的代码 在 Firefox 中运行良好 但在 chrome 中则不行 请让我知道如何解决这个问题 主要思想是根据选择框的选定值调用js函数
  • 如何以编程方式确定我的应用程序正在 iPhone、iPad 或 iPhone 4 上运行?

    我刚刚使用 cocos2d 完成了我的 iPhone 游戏 但在将其发布到 AppStore 之前 我想让它在 iPad 屏幕更大 和 iPhone 4 分辨率更大 上运行 那么 我如何以编程方式确定我的应用程序正在 iPhone iPad
  • Rabbitmq:在无限循环中重新处理失败的消息

    这是我的rabbitmq配置
  • 如何在 ObservableCollection 上执行 foreach lambda 表达式?

    我如何执行foreachObservableCollection 上的 lambda 表达式 没有方法foreach与 ObservableCollection 一起使用 尽管此方法与 List 一起存在 有没有可用的扩展方法 BCL 中默
  • 惰性初始状态 - 它是什么以及如何使用它?

    我是新来反应 Hooks 的 我正在尝试利用useState在我的代码中 当我使用它时 我发现了一个术语 惰性初始状态 https reactjs org docs hooks reference html lazy initial sta
  • 质数 JavaScript

    有人可以指导我在这里获取素数吗 这是家庭作业 所以我不想要答案 但如果有一些指示 我将不胜感激 这真的让我很烦 我想我已经很接近了 但我遇到的问题是 25 和 35 这些不是素数 但这个函数正在返回它们 var getPrimeNumber
  • 在本机应用程序中使用 Webrtc

    我的问题是 1 是否可以在我的 Native App 中拥有一个 WebView 由 Native 框架提供 实例 并扩展它以支持 Webrtc 如果 1 为 是 则可能执行以下操作 1 在 Android 上构建 webrtc 2 在 A
  • Angular 2 和 Angularfire2 中的三向绑定

    我正在尝试使用 AngularFire 2 2 0 0 beta 2 将输入元素三路绑定到 Angular js 2 2 0 0 rc 4 中的 firebase 数据库 我有一个非常简单的 html 例如
  • 安装 ruby​​ 1.9.3 时遇到问题

    我通过命令安装了 ruby 1 9 3rvm install 1 9 3在 mac 的终端上 安装后我收到这些错误 见下文 有人有任何想法来解决这个问题吗 运行 configure prefix Users Keta rvm rubies
  • Flutter pdf 生成图像速度太慢

    我正在 flutter 中开发 pdf 生成器应用程序 但是当我想向 pdf 添加图像时 需要很长时间 我也想知道如何添加多个图像 我使用 3 个库 图像选择器 pdf 打印 这是我的代码 Future getImage async var
  • Caliburn Micro WPF 窗口管理

    我想使用 caliburn micro 启动一个 WPF 应用程序 这样我就可以尽可能地使用 TDD 我之前在 WP7 中使用过 caliburn micro 但 WPF 似乎是另一艘船 并且文档不完整与 WP7 一样 我已经用我的 Boo
  • 是否可以在 Scala 解释器中定义伴随类/模块?

    在 Scala 解释器中进行测试通常很方便 然而 我遇到的一个问题是 我必须重构使用隐式转换的代码 因为定义一个与现有类同名的对象does not使其成为 REPL 中的配套模块 因此 当我翻译回 真实源代码 时 我不能确信我的代码仍然可以
  • 临时和表达行为

    这是明确定义的行为吗 const char p std string Hello std string World c str std cout lt lt p 我不知道 原因 不 这是未定义的行为 两个都std string临时对象和返回
  • Javascript 数组查找效率:关联与存储关联?

    我一直在阅读 他们说关联数组不会给你提供与数组相同的效率 关联数组可以在 O N 时间内查找内容 而数组可以在 O 1 时间内查找内容 这是我的问题 在快速查找值并且不占用太多内存方面 哪一个更有效 联想 var myVars new Ar
  • 在 C# 中创建自定义 ODBC / OLE 驱动程序

    有谁知道如何最好用 C 创建 ODBC 或 OLE 驱动程序 我想要做的是创建一个可以在 Excel 和 Access 中使用的自定义数据源 或者想出另一种方法来做到这一点吗 预先感谢您的回复 C 中有一个 OLE DB 驱动程序的简化版本
  • 根据行数调整 jqGrid 的大小? - 网格高度?

    我遇到了与帖子中详细说明的相同问题根据行数调整 jqGrid 的大小 https stackoverflow com questions 1972806 一些建议 看起来完全合乎逻辑 不起作用 因为当我尝试使用以下命令获取网格的高度时var
  • Thymeleaf 注册页面 - 执行处理器“org.thymeleaf.spring4.processor.attr.SpringInputGeneralFieldAttrProcessor”期间出错

    我正在为一个网站制作一个注册页面 我知道为了创建新用户 需要一个 id 所以我们有这个字段
  • mongodb 性能不佳

    我目前正在使用 mongodb 并且我发现查询性能非常差 可能需要几秒钟 场景如下 我有一个结构文件 id xxx userId yyy a 1 b 2 counter 1 在测试中 userId value could be 1 200
  • Python 多处理池突然停止

    我正在尝试根据我的要求执行并行处理 并且代码似乎可以按预期并行处理 4k 5k 元素 但是 一旦要处理的元素开始增加 代码就会处理一些列表 然后在没有抛出任何错误的情况下 程序突然停止运行 我检查过 程序没有挂起 RAM 可用 我有 16
  • 通过在单元格中键入内容将项目动态添加到 DataGridView ComboBox 列

    我有一个DataGridView有一个ComboBox列 我必须在其下拉列表显示时更新每个组合框的可能值 我还必须使ComboBoxes 能够具有自定义类型的值 当输入新值时 应将其添加到可能值列表中 问题是我得到了无穷多个DataErro