views:

212

answers:

1

If a DataSet contains a column that is a timestamp or other binary value, its associated DataGridView throws an ArgumentException, when displaying any data in that column. That is, assume you have some table containing a binary column such as:

CREATE TABLE [dbo].[DataTest](
    [IdStuff] INT IDENTITY(1,1) NOT NULL,
    [ProblemColumn] TIMESTAMP NOT NULL )

In Visual Studio 2008, add a new Data Source pointing to the suspect table. Drag the table from the Data Source explorer onto the visual designer surface of a new WinForm to automatically create a DataGridView, BindingSource, etc. Execute the application and you will get a runtime exception. Sounds like a defect, right?

If you examine the Columns collection of the DataGridView you will find that it sets the column type to DataGridViewImageColumn. Why? Because, according to Microsoft, .NET assumes that binary columns are images. Indeed, Microsoft affirms that this behavior is by design! See this defect report on Microsoft Connect: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=93639

One could suppress the error dialog by handling the DataError event for the DataGridView, as the dialog politely indicates, but that begs the question. I want to find a way to avoid having an error condition in the first place. That is, I want to have a DataGridViewTextColumn showing a textual representation of the binary data, e.g. "0x1234a8e9433bb2". And I am looking for a generic solution, since my actual code does not use a specific table as in my example above. Rather I put a somewhat arbitrary query into a dataAdapter.SelectCommand, then invoke

dataAdapter.Fill(dataTable)

to auto-generate my dataTable. Since it is the DataGridView that has the (IMHO) bug, I am thinking that I need to check the columns of the data table (i.e. dataTable.Columns[n].DataType.Name.Equals("Byte[]") ? ) and convert any byte arrays to their text forms manually before I connect the dataTable to the DataGridView with

bindingSource.DataSource = dataTable;

My question then:

Is there a simpler or more elegant way to display binary columns in a DataGridView?

(Note that this problem exists with both VS 2005 and VS 2008, .NET 2.0 and .NET 3.5.)

A: 

How about basing your query on a view that does a CAST for that column?

Dave Swersky
Two reasons:(1) I don't think there is a way to do it with CAST in a query. Microsoft shows what is presumably the simplest way to do it, requiring a stored procedure; see http://support.microsoft.com/kb/104829(2) I would like it to be transparent to the user who entered the arbitrary query string.
msorens