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:

  1. Extend the DataGridViewColumn class that just stores original the varbinary column
  2. Implement the ColumnAdded event to hide the original varbinary column, and add your extended column to the DataSet
  3. 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;
            }
        }