DataGridView бросает исключение в диалоге ошибок по умолчанию из-за DataGridViewImageColumn
Я излагаю это, потому что слишком много времени, чтобы найти ответ в Интернете, и это, вероятно, общая проблема - это второй раз, когда я испытал это в своем приложении.
Когда новая строка с DataGridViewImageCell становится видимой и не имеет значения по умолчанию, мой DataGridView выдает следующее исключение:
В DataGridView произошло следующее исключение:
System.ArgumentException: параметр недействителен. в System.Drawing.Image.FromStream(поток потока, логический useEmbeddedColorManagement, Boolean validateImageData) "
В моей настройке я создаю DataGridViewImageColumns в Visual Studio Designer, а затем привязываю эти столбцы к DataColumns в DataTable, устанавливая свойства DataPropertyName в DataGridViewImageColumns в соответствии с DataColumns типа: byte [].
Тем не менее, он по-прежнему выбрасывает это исключение, когда DataGridViewImageColumn в новой строке становится видимым.
Есть два обходных решения, которые работали для меня:
- Снимите флажок "Включить добавление" в конструкторе - затем добавьте строки программно - с помощью кнопок и т.д. - Я думаю, что это то, что я сделал в первый раз.
-
Обработайте событие DataError DataGridView следующим образом:
private void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
if (dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value == DBNull.Value)
{
e.Cancel = true;
}
}
Это вариант, с которым я сейчас пользуюсь, но я не поклонник подавления исключений, и я вижу задержку в создании строки DataGridView из-за броска + Catch обработчиком.
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;
}
}
}
... который не работает.
Другой параметр включал установку столбца CellTemplate в тип, полученный из DataGridViewImageColumn со значением по умолчанию null или DBNull.Value.
Это немного поздно для этого сейчас - я был на этом весь день.
Я, вероятно, собираюсь пойти на свой вариант 2, но может ли кто-нибудь сказать мне, как получить вариант 3/4 для работы? Есть ли лучший подход для этого?
Ответы
Ответ 1
Мое решение: удалите столбец сразу после его добавления (подробная причина в конце). Следующий код удаляет все потенциальные столбцы изображения, вы можете настроить его, если ваша схема не является динамической, и вы знаете, что вы хотите оставить:
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;
вызывает изменение бизнес-объекта! Это причина, по которой я советую просто удалить столбец.
Ответ 2
Эти проблемы вызваны некоторыми типами изображений и 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);
}
Ответ 3
Я получал эту проблему, потому что некоторые из моих изображений мы JPEGS и некоторые были PNG.
Все PNG вызывали ошибку.
Я удалил все PNG, и я не получаю ошибок при прокрутке вниз по сетке.