It's much better to load data using the DataGridView.DataSource.
Example, the following loads a DataTable with data where Picture is a Byte array when loaded into the DataTable.
public static DataTable GetCategories()
{
DataTable table = new DataTable();
using (var cn = new SqlConnection(_connectionString))
{
using (var cmd = new SqlCommand() { Connection = cn })
{
cmd.CommandText = "SELECT CategoryID, CategoryName, Picture FROM dbo.Categories";
cn.Open();
table.Load(cmd.ExecuteReader());
table.Columns["CategoryID"].ColumnMapping = MappingType.Hidden;
}
}
return table;
}
In the form, create a BindingSource, set its DataSource to the method above.
private readonly BindingSource bindingSource = new BindingSource();
public DataGridViewWithImageForm()
{
InitializeComponent();
Shown += OnShown;
}
private void OnShown(object sender, EventArgs e)
{
bindingSource.DataSource = DataOperations.GetCategories();
dataGridView1.DataSource = bindingSource;
}
Now to get at the current row's image.
byte[] imageArray = ((DataRowView)bindingSource.Current).Row.Field<byte[]>("Picture");
You'll know it works by executing the code but let's show the current image in a picturebox.
byte[] imageArray = ((DataRowView)bindingSource.Current).Row.Field<byte[]>("Picture");
ImageConverter converter = new ImageConverter();
pictureBox1.Image = (Image)converter.ConvertFrom(imageArray);