在可编辑单元格中写入值时如何捕获 DataGridView 验证错误?

Posted

技术标签:

【中文标题】在可编辑单元格中写入值时如何捕获 DataGridView 验证错误?【英文标题】:How to catch DataGridView validation Error when I write value in editable cells? 【发布时间】:2013-10-21 19:42:50 【问题描述】:

我已经看到很多涉及数据绑定的解决方案,但我没有数据源。在这种情况下,组合单元格仅适用于 1 行(其他行没有 DataGridViewComboBoxCell)。

我这样设置 DataGridViewComboCell:

DataGridViewComboBoxCell cell = new DataGridViewComboBoxCell();
cell.DisplayStyle = DataGridViewComboBoxDisplayStyle.ComboBox;
cell.Items.AddRange(items.ToArray());   // items is List<string>

我稍后会像这样动态地重新填充它:

_cell.Items.Clear();
_cell.Items.AddRange(this.Data.ResponseOptions.Select( d => d.Description).ToArray());   
//d.Description is of type string

然后我得到了这个讨厌的对话框,上面写着:

DataGridView 出现以下异常: System.ArgumentException:DataGridViewComboBoxCell 值无效。 要替换此默认对话框,请处理 DataError 事件。

顺便说一句,说它不是“有效的”并没有多大帮助。向 MS 发送电子邮件说 Windows 窗体无效是否公平?

我尝试获取单元格的 items 属性并使用 foreach() 和 Add() 调用添加字符串。我仍然得到对话框。

每次我想更新它并从头开始重新创建一个新的 DataGridViewComboCell 时,我都尝试过吹走整个单元格。我仍然得到对话框。

我也尝试过手动覆盖列值(当我没有这个问题时成功)。不过没修好。

当我尝试重新填充组合单元格中的项目时,我似乎只收到此对话框。

现在我只是清除了 DataError 方法。

有什么建议吗?

【问题讨论】:

我以前见过这个错误。当您为单元格设置了 ValueType 并且您提供的数据属于不同类型时,就会发生这种情况。你检查过吗? @ThunderGr:我也是这么想的,但正如您从上面看到的那样,我已经尝试将项目添加为最初和更新中完全相同的类型(以多种方式)。 如果我是你,我会让 DataError 向我打印一份关于添加项目类型和值的消息框的报告。很多时候,您认为所做的与您实际所做的并不相同。尤其是在 C# 中。说实话,我怀疑 null。 您是否尝试让 DataError 向您打印它们导致其触发的值和类型?这是你最有可能的镜头。 DataError 为每个无效的值触发。如果它只为你触发一次,那么只有一个值是无效的。此外,问题可能出在组合的文本值上。不在值列表中。 【参考方案1】:

这个问题有点老了,但我遇到了这个问题,结果证明 ThunderGR 绝对正确。当我让 DataError 打印一份报告时,我开始查看数据库中的值,并注意到它们实际上都是大写字母。只需将我的字符串值更改为全部大写,不再收到错误。

这是一种可能处理 DataError 的方法,尽管我不想一开始就触发它。

    private void dataGridView_DataError(object sender, DataGridViewDataErrorEventArgs e)
    
        try
        
            if (e.Exception.Message == "DataGridViewComboBoxCell value is not valid.")
            
                object value = dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
                if (!((DataGridViewComboBoxColumn)dataGridView.Columns[e.ColumnIndex]).Items.Contains(value))
                
                    ((DataGridViewComboBoxColumn)dataGridView.Columns[e.ColumnIndex]).Items.Add(value);
                
            

            throw e.Exception;
        
        catch (Exception ex)
        
            bool rethrow = ExceptionPolicy.HandleException(ex, "UI Policy");
            if (rethrow)
            
                MessageBox.Show(string.Format(@"Failed to bind ComboBox. "
                + "Please contact support with this message:"
                + "\n\n" + ex.Message));
            
        
    

这样,值将被添加到项目集合中,但仍会在可以记录的地方抛出异常。我使用了消息框,因为我仍然认为用户体验错误消息并联系支持人员修复它很重要。希望这对某人有帮助!

【讨论】:

【参考方案2】:

    使用 WPF。

    将 DataGrid 中的组合框列绑定到列表。

    唱一首歌 - 当您意识到在 WPF 中实现这一点是多么容易之后,您会想要

【讨论】:

啊,根本原因分析 :) 我有权把这个放在意见箱里,就是这样。 我想知道是否可能通过清空组合框,因为在组合框中不再找到列的值,是否可能导致错误/异常? 我应该提到 (1) 我还手动覆盖了该值,并且 (2) 这仅适用于 DGV 中的 1 行。其他行没有组合单元格。【参考方案3】:

我今天遇到了同样的异常,花了很多时间来解决这个问题。事实证明,当为 datagridview 创建新行时,我调用了一个事件处理程序。在该事件处理程序方法中,我错误地将组合框单元格值设置为组合框的项目集合中不存在的值。

因此,简而言之,抛出的异常显示了正确的消息。我只需要找到设置错误值的确切位置。

【讨论】:

【参考方案4】:

您需要将 DataGridViewComboBoxColumn.DataSource 设置为 ResponseOptions 列表,并设置 DataGridViewComboBoxColumn.ValueType = typeof(ResponseOption),而不是添加到 DataGridViewComboBoxColumn.Items。

【讨论】:

【参考方案5】:

我遇到了同样的问题并解决了它,在我分配给数据源的列表中添加了一个与组合框中的空项目相对应的项目。

例如,

var list = controller.GetAllMovementKind();
list.Add(new Model.MovementKind  Code = 0, Name = String.Empty );
movementKindBindingSource.DataSource = list;

GetAllMovementKind 方法返回一个List&lt;Model.MovementKind&gt;

希望对你有帮助。

【讨论】:

【参考方案6】:

要管理和验证 DataGridView 中的可编辑数据,请手动添加以下事件:

myDataGridView.DataError += myDataGridView_DataError;

并以这种方式实现事件:

private void dataGridApprovazioni_DataError(object sender, DataGridViewDataErrorEventArgs e)

    DataGridView dataGridView = (DataGridView)sender;
    dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = DateTime.MinValue;
    MessageBox.Show("Invalid Date Format", "System Info", MessageBoxButtons.OK, MessageBoxIcon.Error);


在此示例中,管理特定列索引中的控件 od DateTime 字段。

【讨论】:

以上是关于在可编辑单元格中写入值时如何捕获 DataGridView 验证错误?的主要内容,如果未能解决你的问题,请参考以下文章

在可重复使用的表格视图单元格中自动触摸按钮

在可重复使用的单元格中显示下载进度

当我在另一个单元格中选择一个值时如何更改单元格的值

easyui combobox 在datagrid中动态加载数据

如何使用`openpyxl`库在Excel中的合并单元格中写入?

JAVA如何向指定的EXCEL单元格中写入数据??