由于DataGridViewImageColumn,DataGridView在默认错误对话框中抛出exception

我这样做是因为在网上找到答案花了太长时间,这可能是一个常见问题 – 这是我第二次在我的应用程序上体验过它。

当具有DataGridViewImageCell的新行变得可见,并且它没有设置默认值时,我的DataGridView将抛出以下exception:

DataGridView中发生以下exception:

System.ArgumentException:参数无效。 在System.Drawing.Image.FromStream(Stream stream,Boolean useEmbeddedColorManagement,Boolean validateImageData)“

在我的设置中,我在Visual Studio Designer中创建DataGridViewImageColumns,然后通过设置DataGridViewImageColumns的DataPropertyName属性以匹配Type:byte []的DataColumns,将这些列绑定到DataTable中的DataColumns。

但是,当新行中的DataGridViewImageColumn变为可见时,它仍会抛出此exception。

有两种解决方法对我有用:

  1. 取消选中Designer中的“启用添加”选项 – 然后以编程方式添加行 – 使用按钮等 – 我认为这是我第一次做的。
  2. 处理DataGridView的DataError事件,如下所示:

    private void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e) { if (dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value == DBNull.Value) { e.Cancel = true; } } 

这是我现在要选择的选项,但我不是压制Exceptions的粉丝,我可以看到由于Handler的throw + Catch而导致DataGridView行的创建延迟。

MSDN( http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewimagecolumn.aspx )表示您可以处理RowsAdded事件并强制使用空值。 我试过这个:

  private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e) { foreach (DataGridViewCell cell in dataGridView1.Rows[e.RowIndex].Cells) { if (cell.GetType() == typeof(DataGridViewImageCell)) { cell.Value = DBNull.Value; } } } 

……哪些不起作用。

另一个选项涉及将Column CellTemplate设置为从DataGridViewImageColumn派生的Type,其默认值为null或DBNull.Value。

现在已经有点晚了 – 我整天都在这里。

我可能会选择我的选项2,但有人能告诉我如何让选项3/4工作吗? 对此有最佳方法吗?

我的解决方案:添加后立即删除列(最后的详细原因)。 以下代码删除了所有可能的图像列,如果您的架构不是动态的,并且您知道要省略的内容,则可能需要自定义此列:

 public Form1() { InitializeComponent(); dataGridView1.ColumnAdded += dataGrid_ColumnAdded; } void dataGrid_ColumnAdded(object sender, DataGridViewColumnEventArgs e) { if (e.Column.CellType == typeof(DataGridViewImageCell)) dataGridView1.Columns.Remove(e.Column); } 

所以说到实际绑定

 DataTable table = dataTableCombo.SelectedItem as DataTable; dataGridView1.DataSource = table; 

在添加(和删除校正)列之后将填充单元格。 并且exception不会以这种方式发生。

另外,在你的dataGridView1_RowsAdded事件处理程序中注意:不仅有e.RowIndex而且还有e.RowCount ,它可以是e.RowCount > 1 ! 所以首先我试过:

 void dataGrid_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e) { for (int i = e.RowIndex; i < e.RowIndex + e.RowCount; i++) { foreach (DataGridViewCell cell in dataGridView1.Rows[i].Cells) { if (cell.GetType() == typeof(DataGridViewImageCell)) { cell.Value = DBNull.Value; } } } } 

但我还是有一些例外。 另外,如果您的绑定是双向的,请注意因为cell.Value = DBNull.Value; 导致业务对象发生变化! 这就是我建议只是删除列的原因。

这个问题是由一些image和varbinary列类型引起的,我的解决方案是创建其他数据数据表并将所有列和单元格值设置为字符串类型:

  var clonedDT = dt.Clone(); for (int i = 0; i < clonedDT.Columns.Count; i++) { clonedDT.Columns[i].DataType = typeof(String); } for (int j = 0; j < dt.Rows.Count;j++ ) { var newRow = clonedDT.NewRow(); for (int i = 0; i < dt.Columns.Count; i++) { newRow.SetField(i, Convert.ToString(item.Value.Rows[j] [i])); } clonedDT.Rows.Add(newRow); } 

我得到了这个问题,因为我的一些图像是JPEGS,有些是PNG。

所有PNG都导致抛出错误。

我删除了所有的PNG,当我向下滚动网格时没有错误。