I recently wrote a simple program for displaying SQL query results in a DataGridView, but noticed it was crashing on varbinary columns. After much searching on the internet, I found out that the default format for a varbinary column is to display it as an image. While that seems like a fine default, there is no way to change it. I found a few examples of how to override, but they seemed awfully complicated, especially since I was binding to a dynamic dataset.
Here is a super simple way to handle this scenario:
-
Extend the DataGridViewColumn class that just stores original the varbinary column
-
Implement the ColumnAdded event to hide the original varbinary column, and add your extended column to the DataSet
-
Implement the CellFormatting event and set the value in the format you want
Example:
class VirtualDataGridViewColumn : DataGridViewColumn
{
private DataGridViewColumn originalColumn;
public VirtualDataGridViewColumn(DataGridViewColumn originalColumn)
: base()
{
this.originalColumn = originalColumn;
}
public DataGridViewColumn OriginalColumn
{
get { return this.originalColumn; }
}
}
private void dataGridView_ColumnAdded(Object sender, DataGridViewColumnEventArgs e)
{
if (e.Column.ValueType == typeof(byte[]))
{
DataGridViewColumn column = new VirtualDataGridViewColumn(e.Column);
column.ValueType = typeof(string);
column.Name = e.Column.Name;
column.DisplayIndex = e.Column.DisplayIndex;
column.CellTemplate = new DataGridViewTextBoxCell();
column.DataPropertyName = e.Column.DataPropertyName;
column.SortMode = DataGridViewColumnSortMode.Programmatic;
e.Column.DataGridView.Columns.Add(column);
e.Column.Visible = false;
}
}
private void dataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
DataGridView currentDataGridView = sender as DataGridView;
if (currentDataGridView.Columns[e.ColumnIndex] is VirtualDataGridViewColumn)
{
VirtualDataGridViewColumn column = currentDataGridView.Columns[e.ColumnIndex] as VirtualDataGridViewColumn;
DataRow dataRow = (currentDataGridView.Rows[e.RowIndex].DataBoundItem as DataRowView).Row;
e.Value = dataRow[column.OriginalColumn.Name];
}
if (e.Value is byte[])
{
e.Value = "0x" + BitConverter.ToString(e.Value as byte[]).Replace("-", "");
e.FormattingApplied = true;
}
}