When you use the Choose Data Source wizard to bind a data source to an ASPxGridView under some circumstances—I haven’t tested all—the Visual Studio data source wizard does not generate image columns. (I tried and verified this with the SQL Server AdventureWorks.Production.ProductPhoto table.) If you manually enter the SQL—select * from [Production].[ProductPhoto]—in the data source wizard then image columns will be rendered/generated in the ASPxGridView and something like system.byte[] will be displayed as the value for that column. (You can verify this by displaying the Production.ProductPhoto.LargePhoto in the ASPxGridView.)
The reason for this is that blob columns, if rendered, are rendered as GridViewDataTextColumn instances. The ASPX will look something like this:
<dxwgv:GridViewDataTextColumn Caption="LargePhoto" FieldName="LargePhoto" VisibleIndex="1">
</dxwgv:GridViewDataTextColumn>
The solution I provided in the Professional DevExpress ASP.NET Controls book was to define a DataItemTemplate for the LargePhoto column, place an ASPxBinaryImage control in the DataItemTemplate, and bind the Value attribute to the image field. That code looks something like this:
<dxwgv:GridViewDataTextColumn Caption="LargePhoto" FieldName="LargePhoto" VisibleIndex="2">
<DataItemTemplate>
<dxe:ASPxBinaryImage ID="ASPxBinaryImage1" runat="server"
Value='<%# Eval("LargePhoto") %>'>
</dxe:ASPxBinaryImage>
</DataItemTemplate>
</dxwgv:GridViewDataTextColumn>
This works of course, but there is an even easier means of display image data directly. The key is to change the grid view column type to the correct class manually. Change the view to the ASPX and modify the column tag to the correct type manually, GridViewDataBinaryImageColumn, set the FieldName property, and you are finished. No template is needed. No ASPxBinaryImage is needed, and there is nothing special to do. The corrected version of the tag will look something like this:
<dxwgv:GridViewDataBinaryImageColumn Caption="LargePhoto" FieldName="LargePhoto" VisibleIndex="1">
</dxwgv:GridViewDataBinaryImageColumn>
This approach (shown above) is the easiest way I have found so far of displaying images directly from a database in an ASPxGridView.
The remaining question is why doesn’t the data source wizard make this leap of faith—figure out that the column is a GridViewDataBinaryImageColumn—for you? The answer is that the image is stored as a varbinary(max)—at least in the AdentureWorks database—and the actual binary bits may not be an image at all.
I also tried to automatically generate the correct column for the Northwind.Employees.Photo column, which is defined as an image, and the wizard ignored the image field again. Neither of the approaches above worked for the Northwind images. In the case of the Northwind database the problem is caused by another problem. The Northwind database has upscaled images from Access and there is some header bits that prevent the image from being displayed directly. Professional DevExpress ASP.NET Controls shows a third approach that uses an IHttpHandler to convert the image bytes into an actual image. (Refer to chapter 2, listing 2-23 for the IHttpHandler or check out earlier blog postings for an online implementation of this approach.)
Sometimes how you skin a cat depends on the cat. (No actual cats were harmed in the writing of this blog.)