c# – DataGridView由于DataGridViewImageColumn而导致默认错误对话框中的异常

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

当具有DataGridViewImageCell的新行变为可见,并且没有设置认值时,DataGridView会抛出以下异常:

The Following Exception occurred in the DataGridView:

System.ArgumentException: Parameter is not valid. at
System.Drawing.Image.FromStream(Stream stream,Boolean
useEmbeddedColorManagement,Boolean validateImageData)”

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

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

有两种解决方法我有用:

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

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

这是我现在正在进行的选择,但是我不是抑制异常的粉丝,并且可以看到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派生的类型,其认值为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;

填充单元格将在添加(和删除校正)列之后发生.而这个例外并不是这样发生的.

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

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...