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

时间:2013-10-20 10:49:37

标签: c# .net winforms datagridview

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

当一个带有DataGridViewImageCell的新行变得可见,并且它没有设置默认值时,我的DataGridView会抛出以下异常:

  

以下异常发生在DataGridView:

中      

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

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

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

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

  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;
            }
        }
    
  3. 这是我现在要使用的选项,但我不是抑制异常的粉丝,我可以看到由于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工作吗?对此有最佳方法吗?

3 个答案:

答案 0 :(得分: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;

在添加(和删除校正)列之后将填充单元格。并且这种情况不会发生异常。

此外,在您的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;会导致业务对象发生变化!这就是我建议只是删除列的原因。

答案 1 :(得分:0)

这个问题是由一些图像和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); 
            }

答案 2 :(得分:0)

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

所有PNG都会导致错误抛出。

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