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

Mik*_*rks 12 .net c# datagridview winforms

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

当具有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;
            }
        }
    
    Run Code Online (Sandbox Code Playgroud)

这是我现在要选择的选项,但我不是压制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;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

......哪些不起作用.

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

现在已经有点晚了 - 我整天都在这里.

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

Csa*_*oth 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);
}
Run Code Online (Sandbox Code Playgroud)

所以当涉及到实际绑定时

DataTable table = dataTableCombo.SelectedItem as DataTable;
dataGridView1.DataSource = table;
Run Code Online (Sandbox Code Playgroud)

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

另外,在您的dataGridView1_RowsAdded事件处理程序中请注意:不仅有e.RowIndexe.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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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